/mocktime

Go package to simplify mocking time functions for deterministic testing

Primary LanguageGoMIT LicenseMIT

mocktime

Build Status Coverage Status Go Reference MIT License

This package provides an easy way to mock specific functions in the time package:

import "github.com/nitroshare/mocktime"

// Same as time.Now()
mocktime.Now()

// Mock Now() and After()
mocktime.Mock()
defer mocktime.Unmock()

// All calls to Now() will return the same time...
mocktime.Now()

// ...until the time is advanced
mocktime.Advance(5 * time.Second)

// ...or explicitly set
mocktime.Set(time.Date(2025, time.May, 1, 0, 0, 0, 0, time.UTC))

// Calls to After() will block until the time is advanced (in another
// goroutine, for example)
<-mocktime.After(5 * time.Second)

// A drop-in replacement for time.Timer is provided:
t := mocktime.NewTimer(10 * time.Second)
<-t.C
t.Stop()

// ...as well as time.Ticker:
t := mocktime.NewTicker(1 * time.Second)
<-t.C
t.Reset(2 * time.Second)
t.Stop()

Advanced Usage

A special utility function is provided that blocks until the next call to After():

chanDone := make(chan any)

go func() {

    // Normally, this will block until Set() or Advance() is called
    <-mocktime.After(5 * time.Second)

    close(chanDone)
}()

// Advance the time to the expiry of the After() call above; we don't need to
// worry if the goroutine has reached the After() call or not when this
// function is called as it will block until After() is called
mocktime.AdvanceToAfter()

// This read is guaranteed to succeed because the read on After() in the
// goroutine is unblocked
<-chanDone