Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
TypeScriptとテストをはじめた
Search
syukai
April 25, 2019
Programming
0
1k
TypeScriptとテストをはじめた
v-kansai #5の登壇資料です。
JavaScriptで書いたVue.jsをTypeScriptに書き直してユニットテストを追加した話
syukai
April 25, 2019
Tweet
Share
More Decks by syukai
See All by syukai
SpringBoot+MyBatisで例外が出たときどこを見るか
syukai
0
270
ブランチ運用とデプロイフローを見直してリリースを楽にする
syukai
4
900
ノート付き-ブランチ運用とデプロイフローを見直してリリースを楽にする
syukai
0
65
一歩ずつ進めるVue.js
syukai
2
390
kanjava20170326
syukai
0
560
Other Decks in Programming
See All in Programming
PHPUnitしか使ってこなかった 一般PHPerがPestに乗り換えた実録
mashirou1234
0
180
42 best practices for Symfony, a decade later
tucksaun
1
180
103 Early Hints
sugi_0000
1
230
Итераторы в Go 1.23: зачем они нужны, как использовать, и насколько они быстрые?
lamodatech
0
770
今年一番支援させていただいたのは認証系サービスでした
satoshi256kbyte
1
250
良いユニットテストを書こう
mototakatsu
7
2.2k
今年のアップデートで振り返るCDKセキュリティのシフトレフト/2024-cdk-security-shift-left
tomoki10
0
200
PHPで学ぶプログラミングの教訓 / Lessons in Programming Learned through PHP
nrslib
2
240
Webエンジニア主体のモバイルチームの 生産性を高く保つためにやったこと
igreenwood
0
330
StarlingMonkeyを触ってみた話 - 2024冬
syumai
3
270
KubeCon + CloudNativeCon NA 2024 Overviewat Kubernetes Meetup Tokyo #68 / amsy810_k8sjp68
masayaaoyama
0
250
SymfonyCon Vienna 2025: Twig, still relevant in 2025?
fabpot
3
1.2k
Featured
See All Featured
BBQ
matthewcrist
85
9.4k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.4k
Building Applications with DynamoDB
mza
91
6.1k
Visualization
eitanlees
146
15k
Making Projects Easy
brettharned
116
5.9k
Navigating Team Friction
lara
183
15k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
2
290
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
26
1.9k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
Large-scale JavaScript Application Architecture
addyosmani
510
110k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
The Cost Of JavaScript in 2023
addyosmani
45
7k
Transcript
5ZQF4DSJQUͱςετ Λ͡Ίͨ WLBOTBJ !TZVLBJ
ࣗݾհ ϢΧΠ !TZVLBJ ීஈͬͯΔ͜ͱ w +BWB w 4QSJOH #PPU
w 7VFKT w /&5ͪΐͬ͜ͱ
લճ ͷ͓͞Β͍ w 5ZQF4DSJQUͷಋೖ͕ݱࡏਐߦܗ w Ϣχοτςετͷಋೖݱࡏਐߦܗ w ࢲ͡Όͳ͍ਓ͕ؤுͬͯΔ͚ͲπϥΠ
5ZQF4DSJQU
5ZQF4DSJQUಋೖ w ͢Ͱʹ+BWB4DSJQUͰग़དྷ্͕ͬͯΔͷΛมߋ w ͬͺΓܕ͕ͳ͍ͱ͠ΜͲ͍ w ίʔυॻ͍ͯͯʮ͜ΕͷܕͳΜ͚ͩͬʁʯͱ͔໘ w Τϥʔݟ͔ͯΒʮ͋ʔͦ͏͍จࣈྻͩͬͨΘʯ w
໊߲ͱ͔74$PEF༷ʹڭ͑ͯ΄͍͠ w εϖϧϛε͕࣮ߦ࣌ʹൃ֮ͱ͔ɾɾɾ
QBDLBHFKTPO w WVFDMJͰ࡞ͬͨΩϨΠͳQBDLBHFKTPOʹඞཁͳͷΛҠ ২ w WVFNBUFSJBM༻ʹ!UZQFTWVFNBUFSJBMΛՃ w OQNJOTUBMM͢ΔͱQBDLBHFKTPO͔Βফ͑Δɾɾɾ
ͱΓ͋͑ͣίϯύΠϧ௨͢ w KTΛUTʹม͑Δ w จ๏ͷҧ͍Λมߋ w FYQPSUɺQSPQ NFUIPE DPNQVUFEɺSPVUFSUT w
BOZ͍ͬͯͬͺ͍ॻ͍ͨ w ͱΓ͋͑ͣίϯύΠϧ௨ͬͯͳΜͱͳ͘ಈ͚͍ͬͨΜ҆ ৺Ͱ͖Δ
<script> JavaScript export default { props: ['model', 'mode'], data() {
return {}; }, computed: { isAmode() { return this.mode === 'A'; } } } <script lang=“ts"> TypeScript import Vue from 'vue' @Component({}) export default class Card extends Vue { @prop() model!: any; @prop() mode!: string; /** computed */ get isAmode() { return this.mode === 'A'; } })
ܕΛݫ֨ʹ͍ͯ͘͠ w ͨΓલ͚ͩͲBOZͰશવخ͘͠ͳ͍ w TIJNTNZ.PEFMEUTΛ࡞ͬͯJOUFSGBDFͱͯ͠ܕΛఆٛ w BOZΛͪΌΜͱͨ͠ܕʹॻ͖͍͑ͯ͘ w JOQVU͕Λͯ͘͠ΕΔΑ͏ʹ͢Δ WNPEFM⇛WNPEFMOVNCFS
<<Employee.d.ts>> // RestAPIͰड͚औΔσʔλͷܕ export = Employee; declare interface Employee {
id: string; name: string; } <<shims-myModel.d.ts>> import _Employee from '@/model/Employee'; export = myModel; declare module myModel { export interface Employee extends _Employee {} } <<template>> <input v-model.number=“age” />
5ZQF4DSJQUରԠͷ্͛ w &4MJOUΛ54MJOUʹมߋ w 54MJOUWVFDMJQMVHJOUZQFTDSJQUͷͷΛ༻
Ϣχοτςετ
͠ΌΓ͍ͨ͜ͱ ΫοΫϒοΫʹ ΄΅ॻ͍ͯ͋ͬͨ Vue.jsΫοΫϒοΫɿVue ίϯϙʔωϯτͷ୯ମςετ https://jp.vuejs.org/v2/cookbook/unit-testing-vue-components.html
ͳͥςετΛ͢ΔͷͰ͔͢ ίϯϙʔωϯτͷ୯ମςετʹͨ͘͞Μͷར͕͋Γ·͢: • ίϯϙʔωϯτ͕Ͳ͏ಈ࡞͖͔͢ͷυΩϡϝϯτΛఏڙ͠ ·͢ • աͳखಈςετͷ࣌ؒΛઅ͠·͢ • ৽͍͠ػೳʹ͓͚ΔόάΛݮΒ͠·͢ •
ઃܭΛվྑ͠·͢ • ϦϑΝΫλϦϯάΛ༰қʹ͠·͢ ࣗಈςετେنͳ։ൃνʔϜ͕ෳࡶͳίʔυϕʔεΛอͭ ͜ͱΛՄೳʹ͠·͢ɻ
࣮ྫ ୯ମςετͷ͖͢͜ͱ: • ࣮ߦ͕ૣ͍͜ͱ • ཧղ͍͢͜͠ͱ • Ұͭͷ࡞ۀ ͚ͩΛςετ͢Δ͜ͱ ʢதུʣ
্هςετʹ͍͔ͭ͘ͷ͕͋Γ·͢: • 1ͭͷςετ͕ҟͳΔ͜ͱʹ͍ͭͯΞαʔγϣϯΛߦ͍ͬͯ·͢ • ίϯϙʔωϯτ͕ଘࡏͰ͖ΔҟͳΔঢ়ଶඳը͖͢ͷΛ͑Δͷ͕͍͠ ҎԼͷྫͰɺςετΛ࣍ͷΑ͏ʹվળ͍͖ͯ͠·͢: • it ϒϩοΫ͝ͱʹ1ͭͷΞαʔγϣϯͷΈ࡞͢Δ • ͘໌֬ͳςετͷઆ໌Λ࣋ͭ • ςετʹඞཁͳ࠷ݶͷσʔλ͚ͩΛఏڙ͢Δ • ॏෳͨ͠ϩδοΫʢwrapper ͷ࡞ͱ username มͷઃఆʣΛϑΝΫτϦؔ ʹϦϑΝΫλϦϯά͢Δ
ͦΕͦΕͱͯ͠ ͱΓ͋͑ͣ͠·͢
+FTU w ެࣜΛݟͳ͕Β+FTUରԠΛਐΊΔ
ࢀߟ w ʮ͡Ίͯͷࣗಈςετʯ w ςετͷߟ͑ํΓ͚ํ
Ϣχοτςετ
ํ w ςετΛཉுΒͳ͍ w 6*ςετఘΊΔ w ֎෦࿈ܞఘΊΔ w QSJWBUFͷςετέʔε͍Βͳ͍ w
͍͖ͳΓશ෦ٻΊͳ͍ʂϢχοτϨϕϧͷ҆શ֬อʂ
ྫʣQSJWBUF prevMonth(): void { this.addMonth(-1); } nextMonth(): void { this.addMonth(1);
} private addMonth(months: number): void { let nextYear: number = Number(this.yyyy); let nextMonth: number = Number(this.mm) + months; if(nextMonth === 13) { nextYear += 1; nextMonth = 1; } else if (nextMonth === 0) { nextYear -= 1; nextMonth = 12; } this.yyyy = nextYear; this.mm = nextMonth; } w ʢ࣮͕ΞϨͳͷ͓͖ͯ͞ʜʣ w BEE.POUIͷҾ͔͔͋͠ Γ͑ͳ͍ w ͦΕҎ֎Λςετ͢Δඞཁͳ͠
ςετέʔε w JU̍ͭͰ̍ςετέʔεʹ͢Δʂ w ͳΜͷςετ͔ͩΘ͔Βͳ͘ͳΔ w JUͷ్தͰೖσʔλΛೖΕସ͑ͳ͍ w Ξαʔγϣϯෳ͋ͬͯΑ͍ ͭͷೖσʔλͰෳͷ߲ɾঢ়ଶΛ֬ೝ͢Δ
ྫʣJU̍ͭͰ̍ςετέʔε <<before>> it('ϙΠϯτ͕ϚΠφεͳΒ0ʹ͢Δ', () => { wrapper.vm.form.points = 1; wrapper.vm.onValidPoint();
expect(wrapper.vm.form.points).toBe(1); wrapper.vm.form.points = -1; wrapper.vm.onValidPoint(); expect(wrapper.vm.form.points).toBe(0); });
ྫʣJU̍ͭͰ̍ςετέʔε <<after>> it(‘onValidPoint ௨ৗ', () => { wrapper.vm.form.points = 1;
wrapper.vm.onValidPoint(); expect(wrapper.vm.form.points).toBe(1); }); it(‘onValidPoint ϚΠφε', () => { wrapper.vm.form.points = -1; wrapper.vm.onValidPoint(); expect(wrapper.vm.form.points).toBe(0); });
"1*ݺͼग़͠ͷςετ w "1*ݺͼग़͠ʹ"YJPTΛ༻ w ϢχοτςετͰ"1*ݺͼग़ͨ͘͠͠ͳ͍ʂ w "YJPTͬͨ"1*ݺͼग़͠ॲཧΛಠཱͤ͞Δ w ্هॲཧΛϞοΫʹஔ͖͑Δ
ྫʣ"QJΛݺͼग़͠Λಠཱ <<EmpoyeesApi.ts>> import axiosBase from '@/module/AxiosBase' let axios = axiosBase.axios;
export default { getEmployees(): Promise<any> { return axios.get('employees'); } } <<hoge.spec.ts>>ɹaxiosࠩ͠ସ͑େมͳͷͰApi͝ͱࠩ͠ସ͑ const getEmployeesMock = jest.fn(); jest.mock('@/module/api/EmployeesApi', () => { return { getEmployees: getEmployeesMock }; })
ը໘දࣔͷςετ w Βͳ͍ʂʂʂʂ w 7VFKT͔ͩΒσʔλ͕େৎͳΒදࣔେৎͩΖʂ w େৎͳΜͩΑʂʂʂʂ w ͱ͍͑USBOTJUJPO͕͏·͘ಈ͍ͯΔ͔ɺσʔλͷ࠶ܭࢉ ͕ͪΌΜͱԠͯ͠Δ͔ؾʹͳΔͱ͜Ζ
⇛Ͳ͏͠Α͏
ςετॻ͍ͯಘͨݟ
ίϯϙʔωϯτখ͘͢͞Δ w Ͱ͔͍ίϯϙʔωϯτπϥΠɻখ͘͞͠Α͏ w ͨΒϞοΫʹཔΖ͏ͱ͢Δ͜ͱʹͳΓɺͦͯ͠ϋϚΔ w ςετέʔεͷΈ߹Θ͕ͤෳࡶʹͳΔ w ςετίʔυ͕͘ͳΓಡΉؾ͕ࣦͤΔ w
ςετέʔεΓͯΔ͔Θ͔Μͳ͍
ΫϥεΛੵۃతʹ࡞Δ w ΫϥεʹΓग़ͯ͠QSJWBUFʹ͢ΕࢀরՕॴ͕ݮͬͯς ετύλʔϯ͕άοͱߜΕΔ w ॻ͍ͯͯؾ͍͚ͮͨͲςετύλʔϯߟ͑Δͷ͕໘ͬͯ ͜ͱӨڹՕॴଟ͍͔Βόάग़͍ͬͯ͢͜ͱͩΑͶ
5ZQF4DSJQU͡Όͳ͍ͱπϥΠ w ผͷҊ݅Ͱ+BWB4DSJQUͷ··ςετͯ͠Έͨ w GVODUJPOͷϞοΫࠩ͠ସ͕͍͑͠ ϦϙδτϦͷςετ͕πϥΠ w Ұ5ZQF4DSJQUΔͱ͏ܕແ͍ͷ໘͍͘͞
·ͩ·ͩΘ͔Βͳ͍ͷͰ ͬͱςετॻ͜͏
͝ਗ਼ௌ ͋Γ͕ͱ͏͍͟͝·ͨ͠