【问题标题】:Does it make sense to test time-based fields ? (golang)测试基于时间的字段有意义吗? (戈朗)
【发布时间】:2014-12-16 20:49:46
【问题描述】:

我有几个字段类型为time.Time 的结构。我想知道测试它们的最佳实践是什么?我是否应该简单地将 time.Time 字段设置为 nil 并测试结构的其余部分(即 reflect.DeepEqual)?否则有没有办法使时间确定? 给定下面的函数,你会如何测试它?

type mystruct struct {
    s string
    time time.Time
}

// myfunc receives a string and returns a struct of type mystruct
// with the same string and the current time.
func myfunc(s string) mystruct {
   return mystruct{s: s, time: time.Now()}
}

【问题讨论】:

  • 这是一个奇怪的问题:为什么不直接测试它们呢? time.Time 怎么可能是零呢?它不能。
  • 测试是什么意思?测试两次是否相同?你可以使用 time.Equal
  • 不要尝试测试time.Now()。 time 包有自己的单元测试。
  • 如果您想检查用户是否没有设置时间,那么只需检查该字段:mystruct.time.IsZero()。有时您无法将结构作为一个整体进行比较。为你想要的结构创建一个Equal 方法。
  • 看看 net/http/cookiejar 如何进行包括时间戳在内的测试:让实际函数有一个 now 参数,该参数在代码中设置为 time.Now(),但允许传入合成时间测试。

标签: unit-testing testing time go mocking


【解决方案1】:

如果你需要为 time.Now() 创建一个假的,你可以创建 TimeProvider 并使用它来获取 real time.Now() 或假它。

这是一个非常简单的例子

package main

import (
    "fmt"
    "time"
)

type TimeProvider interface {
    Now() time.Time
}

type MyTimeProvider struct{}

func (m *MyTimeProvider) Now() time.Time {
    return time.Now()
}

type FakeTimeProvider struct {
    internalTime time.Time
}

func (f *FakeTimeProvider) Now() time.Time {
    return f.internalTime
}
func (f *FakeTimeProvider) SetTime(t time.Time) {
    f.internalTime = t
}

func main() {
    var t MyTimeProvider
    f := FakeTimeProvider{t.Now()}
    fmt.Println(t.Now())
    fmt.Println(f.Now())
}

【讨论】:

    猜你喜欢
    • 2015-05-19
    • 2022-11-18
    • 2018-07-03
    • 2012-04-29
    • 1970-01-01
    • 2015-04-10
    • 2011-04-18
    • 1970-01-01
    • 2017-08-29
    相关资源
    最近更新 更多