Skip to content

LopatkinEvgeniy/clock

Repository files navigation

clock

Build Status GoDoc

Small timer-driven library for mocking time in Go. Clockwork drop in replacement.

Why another one time mocking library?

  • Race free
  • Full featured
  • Redesigned

Example

Suppose we have some type with time-dependent method that we wanna test. Instead of direct use time package we specify the clock field:

const incrementStateDelay = time.Hour

// myType is a type with time-dependent method that we will test.
type myType struct {
	clock clock.Clock
	state int
}

// incrementState increments myType's state with delay.
func (f *myType) incrementState() {
	f.clock.Sleep(incrementStateDelay)
	f.state++
}

Now in tests we just inject FakeClock to the tested struct. This allows us to manipulate time:

func TestExample(t *testing.T) {
	fakeClock := clock.NewFakeClock()

	// create the myType instance with fake clock.
	mt := myType{clock: fakeClock}

	wg := sync.WaitGroup{}
	wg.Add(1)
	go func() {
		mt.incrementState()
		wg.Done()
	}()

	// wait until incrementState is actually sleeping.
	fakeClock.BlockUntil(1)

	// assert state not changed.
	if mt.state != 0 {
		t.Fatalf("Unxepected state, expected=0 actual=%d", mt.state)
	}

	// move time forward and wait for incrementState done.
	fakeClock.Advance(incrementStateDelay)
	wg.Wait()

	// assert state incremented.
	if mt.state != 1 {
		t.Fatalf("Unxepected state, expected=1 actual=%d", mt.state)
	}
}

In production simply inject the real clock instead

mt := myType{clock: clock.NewRealClock()}

Inspired by: