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
1.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
300
ブランチ運用とデプロイフローを見直してリリースを楽にする
syukai
4
970
ノート付き-ブランチ運用とデプロイフローを見直してリリースを楽にする
syukai
0
85
一歩ずつ進めるVue.js
syukai
2
400
kanjava20170326
syukai
0
580
Other Decks in Programming
See All in Programming
AHC 044 混合整数計画ソルバー解法
kiri8128
0
330
いまさら聞けない生成AI入門: 「生成AIを高速キャッチアップ」
soh9834
15
4.5k
AI Coding Agent Enablement - エージェントを自走させよう
yukukotani
13
5.8k
プロダクト横断分析に役立つ、事前集計しないサマリーテーブル設計
hanon52_
2
390
Defying Front-End Inertia: Inertia.js on Rails
skryukov
0
460
5年間継続して開発した自作OSSの記録
bebeji_nappa
0
170
Ruby's Line Breaks
yui_knk
2
470
Making TCPSocket.new "Happy"!
coe401_
1
130
複数ドメインに散らばってしまった画像…! 運用中のPHPアプリに後からCDNを導入する…!
suguruooki
0
470
remix + cloudflare workers (DO) docker上でいい感じに開発する
yoshidatomoaki
0
130
Building a macOS screen saver with Kotlin (Android Makers 2025)
zsmb
1
140
S3静的ホスティング+Next.js静的エクスポート で格安webアプリ構築
iharuoru
0
220
Featured
See All Featured
Designing for humans not robots
tammielis
252
25k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
119
51k
Mobile First: as difficult as doing things right
swwweet
223
9.6k
Documentation Writing (for coders)
carmenintech
69
4.7k
StorybookのUI Testing Handbookを読んだ
zakiyama
29
5.6k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
60k
Making the Leap to Tech Lead
cromwellryan
133
9.2k
How to Think Like a Performance Engineer
csswizardry
23
1.5k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
129
19k
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Δͱ͏ܕແ͍ͷ໘͍͘͞
·ͩ·ͩΘ͔Βͳ͍ͷͰ ͬͱςετॻ͜͏
͝ਗ਼ௌ ͋Γ͕ͱ͏͍͟͝·ͨ͠