go-cmpを使ってる場合の時間のチェックを緩くする

2 min読了の目安(約1800字TECH技術記事

結論から言うと、

DB への insert 時間だったり、mock の api の呼び出しだったり 時刻の insert に多少の時間が発生する

そんな時は cmpopts.EquateApproxTimeを使いましょうという話

以下サンプル

以下の HogeHoge() メソッドをテストする

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() { fmt.Println("hello world") }

type Hoge struct {
	CreatedAt time.Time
}

func HogeHoge() *Hoge {
	n := rand.Intn(5)

	return &Hoge{
		CreatedAt: time.Now().Add(time.Duration(n) * time.Second),
	}
}

これがテストコード

大事なところは TestHogeHoge_successcmpopts.EquateApproxTime(5*time.Second) option を渡して 5sec の時間のズレを許容しているところ

package main

import (
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
)

func TestHogeHoge_fail(t *testing.T) {
	expect := &Hoge{
		CreatedAt: time.Now(),
	}

	if diff := cmp.Diff(HogeHoge(), expect); diff != "" {
		t.Errorf("error case:\n(-got +want)\n%v", diff)
	}

	if diff := cmp.Diff(HogeHoge(), expect, cmpopts.EquateApproxTime(5*time.Second)); diff != "" {
		t.Errorf("error case:\n(-got +want)\n%v", diff)
	}
}

func TestHogeHoge_success(t *testing.T) {
	expect := &Hoge{
		CreatedAt: time.Now(),
	}

	if diff := cmp.Diff(HogeHoge(), expect, cmpopts.EquateApproxTime(5*time.Second)); diff != "" {
		t.Errorf("error case:\n(-got +want)\n%v", diff)
	}
}

結果はこちら

$ go test -v .
=== RUN   TestHogeHoge_fail
    main_test.go:17: error case:
        (-got +want)
          &main.Hoge{
        -       CreatedAt: s"2020-10-12 14:59:36.485052 +0900 JST m=+1.000848117",
        +       CreatedAt: s"2020-10-12 14:59:35.485052 +0900 JST m=+0.000847678",
          }
--- FAIL: TestHogeHoge_fail (0.00s)
=== RUN   TestHogeHoge_success
--- PASS: TestHogeHoge_success (0.00s)
FAIL

以上、go-cmp を使ってる場合の時間のチェックを緩くする話