在测试代码中有多种模拟或存根 time.Now() 的方法:
func CheckEndOfMonth(now time.Time) {
...
}
CheckEndOfMonth(now func() time.Time) {
// ...
x := now()
}
type Clock interface {
Now() time.Time
}
type realClock struct {}
func (realClock) Now() time.Time { return time.Now() }
func main() {
CheckEndOfMonth(realClock{})
}
type nowFuncT func() time.Time
var nowFunc nowFuncT
func TestCheckEndOfMonth(t *Testing.T) {
nowFunc = func() time.Time {
return time.Now()
}
defer function() {
nowFunc = time.Now
}
// Test your code here
}
type TimeValidator struct {
// .. your fields
clock func() time.Time
}
func (t TimeValidator) CheckEndOfMonth() {
x := t.now()
// ...
}
func (t TimeValidator) now() time.Time {
if t.clock == nil {
return time.Now() // default implementation which fall back to standard library
}
return t.clock()
}
每个都有它自己的优点和缺点。最好的方法是将生成时间的函数和使用时间的处理部分分开。
这个Golang 中的 Post Stubing Time详细介绍了它,并且有一个示例可以轻松测试具有时间依赖性的函数。