This is all possible and quite neat to dive into the specifics, but if you really want to be able swap a std lib call, just turn it into a variable and change it.
// code.go
var now = time.Now
// code_test.go
func TestCode(t *testing.T) {
nowSwap := now
t.Cleanup (func() {
now = nowSwap
}
now = func() time.Time {
return time.Date(...)
}
}
Examples
Code: https://github.com/open-telemetry/opentelemetry-go/blob/main...
Test: https://github.com/open-telemetry/opentelemetry-go/blob/490f...This is often the path of pain: https://google.github.io/styleguide/go/best-practices#global....
Just for the record - this is package local - it's fine within the package it is defined in, but no other package will use the implementation, they will all use the standard library.
Others have linked to the much more "fun" https://github.com/bouk/monkey which is an actual monkey patch, in that it changes the code that is called from anywhere in the runtime
The point of the OP is that it changes calls to `time.Now` regardless of whether the code that's calling it uses your variable or not.
That is a useful pattern, though I was unclear on why `t.Cleanup` and not `defer`. In case others are curious, too:
> Parallel subtestsWith t.Run(..., func(t testing.T) { t.Parallel(); ... }), the parent test function can return (and thus run its defers) before parallel subtests actually finish.*