What approach do you use to mock time.Now() ?

polaris · · 557 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Here is what I&#39;ve found after quick search:</p> <ol> <li>Pass Clock interface as a dependency (works for parallel test run)</li> <li>Call time.Now() but use monkey patching library (for ex bouk/monkey) that rewrites running executable (only sequential test run)</li> <li>Pass time.Time as an argument (may work for parallel test run)</li> <li>Own package-level time.Now function that could be replaced in tests (only sequential test run)</li> <li>Third-party (for ex ssoroka/ttime) with same API as time package, i.e. package-level functions (only sequential test run)</li> </ol> <hr/>**评论:**<br/><br/>peterbourgon: <pre><p>After lots of experimentation, I now always pass the specific functions I use in package time as dependencies to the component or function. I guess this maps to your option 1. For example,</p> <pre><code>func foo(now func() time.Time, ...) func newBar(after func(time.Duration) &lt;-chan time.Time, ...) *bar foo(time.Now, ...) // called this way in real code foo(func() time.Time { return fixedTime }, ...) // and this way in tests </code></pre> <p>If my functions or components don&#39;t need to create e.g. tickers but rather just use them, I find it&#39;s often nicer to pass the actual chan, i.e.</p> <pre><code>func process(newTicker func(time.Duration) *time.Ticker, ...) // eh func process(tick &lt;-chan time.Time, ...) // sometimes nicer </code></pre> <p>One advantage here is that in the body of the function, I can simply range over the tick chan, using it to control the function/goroutine lifecycle by stopping the ticker in the calling context. Sometimes that&#39;s useful.</p></pre>UnlikelyToBeEaten: <pre><p>I usually just insult its mother.</p></pre>htonl: <pre><p>I&#39;ve used <a href="https://github.com/facebookgo/clock" rel="nofollow">facebookgo/clock</a> before, works ok.</p></pre>jerf: <pre><p>I wrote, and make extensive use of, <a href="https://github.com/thejerf/abtime" rel="nofollow">abtime</a>. This also supports the tickers and such.</p> <p>In my opinion, you can&#39;t support the original time API and have this sort of thing work well. You need too much control for testing; for instance, I&#39;ve got tests where I have multiple timers and I fire them in different possible orders in my test code. I also think that either you can fully replace the time package completely 100% compatibly, or you shouldn&#39;t even try, so I don&#39;t even try since you can&#39;t re-export the types. If Go gets type aliasing I may look again at having a more transparent drop-in library, however I expect my tickers and timers will always require an additional ID parameter.</p> <p>Oh, and I&#39;m not sure I&#39;d even trust that monkeypatching library for test code. No criticism intended of the author bouk, who I believe responsibly documented what the library does, but that&#39;s not really something I&#39;d even want in my test stack.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

557 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传