Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
TypeScriptとテストをはじめた
Search
syukai
April 25, 2019
Programming
1.2k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
TypeScriptとテストをはじめた
v-kansai #5の登壇資料です。
JavaScriptで書いたVue.jsをTypeScriptに書き直してユニットテストを追加した話
syukai
April 25, 2019
More Decks by syukai
See All by syukai
SpringBoot+MyBatisで例外が出たときどこを見るか
syukai
0
390
ブランチ運用とデプロイフローを見直してリリースを楽にする
syukai
4
1.4k
ノート付き-ブランチ運用とデプロイフローを見直してリリースを楽にする
syukai
0
110
一歩ずつ進めるVue.js
syukai
2
430
kanjava20170326
syukai
0
640
Other Decks in Programming
See All in Programming
AHC070解法紹介
eijirou
0
130
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
250
選挙速報を多くのユーザーへ 届ける Live Activities 設計
hamayokokuririn
0
150
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
820
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
300
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
350
市販E-Readerを乗っ取れ 〜Embedded Swiftで電子ペーパーガジェットを制御する〜
trickart
0
200
すこし踏み込む CancellationToken
htkym
2
690
cdk deploy JawsSonic #MARATHONしながらAWSリソースをデプロイしてみよう
akihisaikeda
2
140
WebMCP Challenge に星空観察アプリで参加した話
okajun35
0
190
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
520
setup-vp GitLab対応の裏側
naokihaba
0
120
Featured
See All Featured
GitHub's CSS Performance
jonrohan
1033
470k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
Building the Perfect Custom Keyboard
takai
2
880
Balancing Empowerment & Direction
lara
6
1.3k
Unsuck your backbone
ammeep
672
58k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
470
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
670
Rails Girls Zürich Keynote
gr2m
96
14k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
How to make the Groovebox
asonas
2
2.4k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.6k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
500
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Δͱ͏ܕແ͍ͷ໘͍͘͞
·ͩ·ͩΘ͔Βͳ͍ͷͰ ͬͱςετॻ͜͏
͝ਗ਼ௌ ͋Γ͕ͱ͏͍͟͝·ͨ͠