go get github.com/ankorstore/yokai/fxclock
This module provides a clockwork.Clock instance for your application, that you can use to control time.
This module is intended to be used alongside the fxconfig module.
To load the module in your Fx application:
package main
import (
"time"
"github.com/ankorstore/yokai/fxclock"
"github.com/ankorstore/yokai/fxconfig"
"github.com/jonboulle/clockwork"
"go.uber.org/fx"
)
func main() {
fx.New(
fxconfig.FxConfigModule, // load the module dependencies
fxclock.FxClockModule, // load the module
fx.Invoke(func(clock clockwork.Clock) { // invoke the clock
clock.Sleep(3 * time.Second)
}),
).Run()
}
This module provides a clockwork.Clock instance, ready to inject in your code.
This is particularly useful if you need to control time (set time, fast-forward, ...).
For example:
package service
import (
"github.com/jonboulle/clockwork"
)
type ExampleService struct {
clock clockwork.Clock
}
func NewExampleService(clock clockwork.Clock) *ExampleService {
return &ExampleService{
clock: clock,
}
}
func (s *ExampleService) Now() string {
return s.clock.Now().String()
}
See the underlying vendor documentation for more details.
This module provides a *clockwork.FakeClock instance, that will be automatically injected as clockwork.Clock
in your constructors in test
mode.
By default, the fake clock is set to time.Now()
(your test execution time).
You can configure the global time in your test in your testing configuration file (for all your tests), in RFC3339 format:
# ./configs/config_test.yaml
modules:
clock:
test:
time: "2006-01-02T15:04:05Z07:00" # time in RFC3339 format
You can also override this value, per test, by setting the MODULES_CLOCK_TEST_TIME
env var.
You can populate
the *clockwork.FakeClock from your test to control time:
package service_test
import (
"testing"
"time"
"github.com/ankorstore/yokai/fxsql"
"github.com/foo/bar/internal"
"github.com/foo/bar/internal/service"
"github.com/jonboulle/clockwork"
"github.com/stretchr/testify/assert"
"go.uber.org/fx"
)
func TestExampleService(t *testing.T) {
testTime := "2025-03-30T12:00:00Z"
expectedTime, err := time.Parse(time.RFC3339, testTime)
assert.NoError(t, err)
t.Setenv("MODULES_CLOCK_TEST_TIME", testTime)
var svc service.ExampleService
var clock *clockwork.FakeClock
internal.RunTest(t, fx.Populate(&svc, &clock))
// current time as configured above
assert.Equal(t, expectedTime, svc.Now()) // 2025-03-30T12:00:00Z
clock.Advance(5 * time.Hour)
// current time is now advanced by 5 hours
assert.Equal(t, expectedTime.Add(5*time.Hour), svc.Now()) // 2025-03-30T17:00:00Z
}
See tests example for more details.