Skip to content

Latest commit

 

History

History

fxclock

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Fx Clock Module

ci go report codecov Deps PkgGoDev

Fx module for clockwork.

Installation

go get github.com/ankorstore/yokai/fxclock

Features

This module provides a clockwork.Clock instance for your application, that you can use to control time.

Documentation

Dependencies

This module is intended to be used alongside the fxconfig module.

Loading

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()
}

Usage

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.

Testing

This module provides a *clockwork.FakeClock instance, that will be automatically injected as clockwork.Clock in your constructors in test mode.

Global time

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.

Time control

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.