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

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

问题描述

我们的部分代码对时间敏感,我们需要保留一些内容,然后在30-60秒之内释放它,等等,我们只需执行time.Sleep(60 * time.Second)

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

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

我想知道是否有另一种方法可以在全局范围内存根time.Now().也许要进行系统调用来更改系统时钟?

也许我们可以编写自己的时间包,该时间包基本上包裹了时间包,但允许我们对其进行更改?

我们当前的实施效果很好,我是初学者,我很好奇是否有人有其他想法?

解决方案

通过实现自定义界面,您已经是正确的方式.我认为您可以使用您发布的golang螺母线程中的以下建议:


type Clock interface {
  Now() time.Time
  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天全站免登陆