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
Goの時刻に関するテスト/Testing time in Go
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Kentaro Kawano
July 07, 2017
Programming
170
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Goの時刻に関するテスト/Testing time in Go
Goの時刻に関するテスト
Kentaro Kawano
July 07, 2017
More Decks by Kentaro Kawano
See All by Kentaro Kawano
Goでのレシーバーとnilの関係 / Receiver and nil relationship in Go
kawaken
0
550
Starting Python
kawaken
0
170
AWS Lambda + Go
kawaken
0
160
goaのdesignをラクに書く/Write goa design easily
kawaken
0
140
Goでのチーム開発とコード管理の悩み/Team development and code management in Go
kawaken
0
140
Pyvmomiとansibleのdynamic inventory
kawaken
0
150
Other Decks in Programming
See All in Programming
複数ドメインを一つのアプリに統合するFlutterの設計と運用_FlutterKaigi2026登壇資料(須永高弘)
takahirosunaga
0
140
AI時代のシニアエンジニアとは
yosuke_furukawa
PRO
14
11k
LLM 101
dalinaum
0
460
Event is what happens
moro
2
3.4k
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
1.8k
[DroidKnights 2026] Workflow AX: From Auto-Documented Policies to E2E Testing
raeminkang
0
510
Modernizing iOS Apps
seyfoyun
0
150
高橋メソッドでCVE解説シリーズ 〜CVE-2026-112816〜
hakkadaikon
0
200
Coding with AI: How to trust the storyteller (AWS Community Day Adria, Ljubljana 2026)
slobodan
0
140
Goコンパイラを作ってGoをもっと理解する / Build a Go compiler to better understand Go
ikura_hamu
0
120
現場と育てるRailsモデリング 〜Spreadsheetから始めたモデル設計〜
siroemk
2
1.2k
React Native経験者が Flutterを30⽇間触って驚いたこと
3saito
0
140
Featured
See All Featured
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
560
Exploring anti-patterns in Rails
aemeredith
4
560
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
2
390
Claude Code のすすめ
schroneko
67
230k
brightonSEO & MeasureFest 2025 - Winning Strategies for Black Friday CRO & PPC - Christian Goodrich
cargoodrich
3
890
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
12k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.2k
sira's awesome portfolio website redesign presentation
elsirapls
0
490
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.7k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
23k
The Language of Interfaces
destraynor
162
27k
So, you think you're a good person
axbom
PRO
2
2.2k
Transcript
Goͷ࣌ࠁʹؔ͢Δςετ 2017/07/07 Umeda.go #2
ࣗݾհ • Տ ݈ଠ࿕ (@kawaken) • γφδʔϚʔέςΟϯάʢגʣ • ϓογϡ௨ج൫ɺLINE৴ج൫ •
Go3͘Β͍ • goaͷίʔυεχϖοτ࡞ͬͯ·͢
࣌ࠁͷςετͷ͠͞ʁ
func CanDeliver() bool { hour := time.Now().Hour() // 8࣌ʙ20࣌ͳΒ৴Մೳ return
8 <= hour && hour <= 20 } ࣌ࠁΛऔಘͯ͠அ͢Δfunc
ςετํ • 8࣌ʙ20࣌: trueͰ͋Δ͜ͱΛ֬ೝ͢Δ • 21࣌ʙ7࣌: falseͰ͋Δ͜ͱΛ֬ೝ͢Δ
μϝͳςετ func TestCanDeliver(t *testing.T) { hour := time.Now().Hour() expected :=
8 <= hour && hour <= 20 // ಉ͡ॲཧ result := CanDeliver() if expected == result { t.Log("OK") } else { t.Fatal("NG") } }
࣌ࠁͷςετͷ͠͞ • time.Now ৗʹҧ͏Λฦ͢ • ͕࣌ؒܦա͠ͳ͍ͱύλʔϯΛཏͰ͖ͳ͍
͍ΖΜͳςετͷύλʔϯ • ݄ลΓͷि • څྉ͕ٳ • य़ͷɺळͷ • ৼସٳ •
2݄29
࣮ͱςετͷύλʔϯ
࣮ͱςετͷύλʔϯ 1. ֎෦͔Βͷೖ 2. ελϒ 3. αʔυύʔςΟʔͷύοέʔδ
1. ֎෦͔Βͷೖ
func CanDeliver(hour int) bool { // 8࣌ʙ20࣌ͳΒ৴Մೳ return 8 <=
hour && hour <= 20 } ͦͦtime.NowΛ͏ඞཁ͕ͳ͍
func TestCanDeliver(t *testing.T) { cases := []struct { hour int
want bool }{ {7, false}, {8, true}, {20, true}, {21, false}, } for _, c := range cases { got := CanDeliver(c.hour) if got != c.want { t.Errorf("CanDeliver(%d) => %t, want %t", c.hour, got, c.want) } } }
2. ελϒ
var now = time.Now // time.NowΛnowʹೖΕ͓ͯ͘ func CanDeliver() bool {
hour := now().Hour() // nowΛ༻ͯ࣌͠ࠁΛऔಘ // 8࣌ʙ20࣌ͳΒ৴Մೳ return 8 <= hour && hour <= 20 } now Λςετ࣌ʹஔ͖͑Δ
func fakeHour(hour int) { // ݻఆͷtime.TimeΛฦ͢funcͰnowΛஔ͖͑Δ now = func() time.Time
{ return time.Date(2017, 7, 7, hour, 0, 0, 0, time.Local) } } func TestCanDeliver(t *testing.T) { // snip... for _, c := range cases { fakeHour(c.hour) // fakeHourͰ࣌ࠁΛॻ͖͑Δ got := CanDeliver() if got != c.want { t.Errorf("hour: %d, CanDeliver() => %t, want %t", c.hour, got, c.want) } } now = time.Now // reset time }
3. αʔυύʔςΟʔͷύοέʔδ
code.cloudfoundry.org/clock • timeͷସͱͯ͠͏ύοέʔδ • ͕ؔ๛ • ςετ࣌ʹɺclock/fakeclock/FakeClockΛ༻
var myClock = clock.NewClock() // myClockʹclock.ClockΛೖ func CanDeliver() bool {
hour := myClock.Now().Hour() // myClockΛ༻ͯ࣌͠ࠁΛऔಘ // 8࣌ʙ20࣌ͳΒ৴Մೳ return 8 <= hour && hour <= 20 } myClock Λςετ࣌ʹஔ͖͑Δ
func fakeHour(hour int) { // ࢦఆ͞Εͨ࣌ࠁ͔Β։࢝͢ΔΑ͏ʹFakeClockͰஔ͖͑Δ myClock = fakeclock.NewFakeClock(time.Date(2017, 7,
7, hour, 0, 0, 0, time.Local)) } func TestCanDeliver(t *testing.T) { // snip... for _, c := range cases { fakeHour(c.hour) // fakeHourͰ࣌ࠁΛॻ͖͑Δ got := CanDeliver() if got != c.want { t.Errorf("hour: %d, CanDeliver() => %t, want %t", c.hour, got, c.want) } } myClock = clock.NewClock() // reset time }
ϞϠϞϠϙΠϯτ • ґଘੑΛ֎෦͔Βೖ • Ͳ͔͜Ͱ time.Now ݺͳ͍ͱ͍͚ͳ͍ • ελϒαʔυύʔςΟʔύοέʔδ •
time.Now Λ༻͍͚ͯ͠ͳ͍
ૉʹtime.Now͍͍ͨ
4. ֎෦͔Βͷೖ̎
func CanDeliver(hour int) bool { // 8࣌ʙ20࣌ͳΒ৴Մೳ return 8 <=
hour && hour <= 20 } func CanDeliverNow() bool { hour := time.Now().Hour() return CanDeliver(hour) }
5. Monkey patch
github.com/bouk/monkey • GoͰϞϯΩʔύονΛ࣮ݱ͢Δύοέʔδ • ؔϙΠϯλΛࠩ͠ସ͑ͨΓͰ͖Δ • શͯͷڥͰಈ࡞͢ΔΘ͚Ͱͳ͍Έ͍ͨ
func CanDeliver() bool { hour := time.Now().Hour() // 8࣌ʙ20࣌ͳΒ৴Մೳ return
8 <= hour && hour <= 20 }
func fakeHour(hour int) { // time.NowΛࢦఆͷ࣌ࠁΛฦ͢funcͰஔ͖͑Δ monkey.Patch( time.Now, func() time.Time
{ return time.Date(2017, 7, 7, hour, 0, 0, 0, time.Local) }, ) } func TestCanDeliver(t *testing.T) { // snip... for _, c := range cases { fakeHour(c.hour) // fakeHourͰ࣌ࠁΛॻ͖͑Δ got := CanDeliver() if got != c.want { t.Errorf("hour: %d, CanDeliver() => %t, want %t", c.hour, got, c.want) } } monkey.Unpatch(time.Now) // reset time }
6. timeύοέʔδΛ֦ு͢Δ
// time.Now func Now() Time { sec, nsec := now()
return Time{sec + unixToInternal, nsec, Local} }
NowΛ͍͡Ε͍͍ͷͰʁ
/* src/time/time.go */ var fakeTime Time // χηͷ࣌ࠁ func Fake(t
Time) { fakeTime = t } func ResetFake() { fakeTime = Time{} } func Now() Time { if !fakeTime.IsZero() { return fakeTime } sec, nsec := now() return Time{sec + unixToInternal, nsec, Local} }
func CanDeliver() bool { hour := time.Now().Hour() // 8࣌ʙ20࣌ͳΒ৴Մೳ return
8 <= hour && hour <= 20 }
func fakeHour(hour int) { time.Fake(time.Date(2017, 7, 7, hour, 0, 0,
0, time.Local)) } func TestCanDeliver(t *testing.T) { // snip... for _, c := range cases { fakeHour(c.hour) // fakeHourͰ࣌ࠁΛॻ͖͑Δ got := CanDeliver() if got != c.want { t.Errorf("hour: %d, CanDeliver() => %t, want %t", c.hour, got, c.want) } } time.ResetFake() // reset time }
΄ΜͱʹͣΕͯΜͷ͔ͳʁʁʁ % /usr/local/go1.8.3_faketime/bin/go test -v ./timepkg === RUN TestCanDeliver ---
PASS: TestCanDeliver (0.00s) sample_test.go:22: 2017-07-07 07:00:00 +0900 JST sample_test.go:22: 2017-07-07 08:00:00 +0900 JST sample_test.go:22: 2017-07-07 20:00:00 +0900 JST sample_test.go:22: 2017-07-07 21:00:00 +0900 JST PASS ok github.com/kawaken/golang-time-testing/timepkg 0.466s
·ͱΊ ࣌ࠁͷςετ͍͕͠ɺճආํ๏͋Δ 1. ࣌ࠁͷऔಘͱɺ࣌ࠁΛॲཧ͢Δͱ͜ΖΛ͚Δ 2. code.cloudfoundry.org/clock ͕ແʁ 3. monkey͋Γʁ