有没有一种简单的方法可以在测试期间全局排除 time.Now() ? [英] Is there an easy way to stub out time.Now() globally during test?

查看:20
本文介绍了有没有一种简单的方法可以在测试期间全局排除 time.Now() ?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的部分代码是时间敏感的,我们需要能够保留一些东西,然后在 30-60 秒内释放它等等,我们可以做一个 time.Sleep(60 * time.Second)

我刚刚实现了时间接口,并且在测试期间使用了时间接口的存根实现,类似于 这个 golang-nuts 讨论.

然而,time.Now() 在多个站点中被调用,这意味着我们需要传递一个变量来跟踪我们实际睡了多少时间.

我想知道是否有其他方法可以在全局范围内排除 time.Now().也许进行系统调用以更改系统时钟?

也许我们可以编写自己的时间包,它基本上环绕时间包但允许我们更改它?

我们目前的实现效果很好,我是一个围棋初学者,我很想知道是否有人有其他想法?

解决方案

通过实现自定义界面,您已经走在正确的道路上.我认为您使用了您发布的 golang 坚果线程中的以下建议:

<小时>

type 时钟接口 {现在()时间.时间After(d time.Duration) <-chan time.Time}

<块引用>

并提供具体的实现

type realClock struct{}func (realClock) Now() time.Time { return time.Now() }func (realClock) After(d time.Duration) <-chan time.Time { return time.After(d) }

<块引用>

和测试实现.

<小时>

原文

在进行测试(或一般情况下)时更改系统时间是一个坏主意.您不知道在执行测试时什么取决于系统时间,并且您不想通过花费数天的时间调试来找出困难的方法.只是不要这样做.

也没有办法在全局范围内隐藏时间包,这样做是不行的使用界面解决方案无法做的更多事情.您可以编写自己的时间包它使用标准库并提供一个功能来切换到模拟时间库测试是否是您需要与困扰您的界面解决方案传递的时间对象.

设计和测试代码的最佳方法可能是使尽可能多的代码无状态.将您的功能拆分为可测试的无状态部分.分别测试这些组件要容易得多.此外,更少的副作用意味着更容易让代码并发运行.

Part of our code is time sensitive and we need to able to reserve something and then release it in 30-60 seconds etc, which we can just do a time.Sleep(60 * time.Second)

I have just implemented time interface and during test use a stubbed implementation of the time interface, similar to this golang-nuts discussion.

However, time.Now() is called in multiple sites which means we need to pass a variable around to keep track of how much time we have actually slept.

I was wondering if there is an alternative way to stub out time.Now() globally. Maybe making a system call to change the system clock?

Maybe we can write our own time package which basically wraps around the time package but allows us to change it?

Our current implementation works well, I am a go beginner and I am curious to see if anyone has other ideas?

解决方案

With implementing a custom interface you are already on the right way. I take it you use the following advise from the golang nuts thread you've posted:


type Clock interface {
  Now() time.Time
  After(d time.Duration) <-chan time.Time
}

and provide a concrete implementation

type realClock struct{}
func (realClock) Now() time.Time { return time.Now() }
func (realClock) After(d time.Duration) <-chan time.Time { return time.After(d) }

and a testing implementation.


Original

Changing the system time while making tests (or in general) is a bad idea. You don't know what depends on the system time while executing tests and you don't want to find out the hard way by spending days of debugging into that. Just don't do it.

There is also no way to shadow the time package globally and doing that would not do anything more you couldn't do with the interface solution. You can write your own time package which uses the standard library and provides a function to switch to a mock time library for testing if it is the time object you need to pass around with the interface solution that is bothering you.

The best way to design and test your code would probably be to make as much code stateless as possible. Split your functionality in testable, stateless parts. Testing these components separately is much easier then. Also, less side effects means that it is much easier to make the code run concurrently.

这篇关于有没有一种简单的方法可以在测试期间全局排除 time.Now() ?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆