関連記事
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ
概要
以下、自分用のメモです。
Go1.24で実験的機能として追加されて、Go1.25で晴れてリリースされた testing/synctest パッケージさん。
非同期処理のユニットテストでよくある Flaky Test(不安定なテスト) が発生しないようにするためのパッケージですね。
その中に fake clock 機能があり、これは文字通り「偽の時計」という意味です。time.Sleep(3*time.Second) としても実際にはスリープせずにすぐに処理が進みます。ですが、time.Since(start) で経過時間を取るとちゃんと3秒経過しているとなる。
サンプル
synctest/fakeclock/time_test.go
package fakeclock import ( "testing" "testing/synctest" "time" "github.com/nalgeon/be" ) const ( SleepTime = 2 * time.Second ) func TestNoFakeClock(t *testing.T) { start := time.Now() { // 普通に時間が流れるので指定時間スリープする time.Sleep(SleepTime) } elapsed := time.Since(start) be.Equal(t, elapsed, SleepTime) // 実際の結果は実行時に変化し、基本的に厳密な一致は出来ないことがほとんど } func TestUseFakeClock(t *testing.T) { synctest.Test(t, func(t *testing.T) { start := time.Now() { // Fake-Clockが使用されるためsynctest内では一瞬で完了する time.Sleep(SleepTime) } elapsed := time.Since(start) be.Equal(t, elapsed, SleepTime) // Fake-Clockにより結果が一致する }) }
Taskfile.yml
# https://taskfile.dev version: '3' tasks: default: cmds: - go test . -v ignore_error: true
実行結果
$ task task: [default] go test . -v === RUN TestNoFakeClock time_test.go:23: want 2000000000, got 2000922653 --- FAIL: TestNoFakeClock (2.00s) === RUN TestUseFakeClock --- PASS: TestUseFakeClock (0.00s) FAIL FAIL github.com/devlights/try-golang/examples/synctest/fakeclock 2.004s FAIL
fake clockを使っている版(synctestパッケージを利用している方)は、何回やってもパスします。
通常、このような標準ライブラリが提供する機能でモッキングとか結構面倒なのですが、synctest.Test() ってすれば良いだけなので楽ですね。
参考情報
Goのおすすめ書籍
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。