如何在Elixir中模拟当前时间

时间:2018-10-14 11:19:05

标签: datetime testing elixir ecto

我有一些测试取决于当前时间,到目前为止还无法找到解决方案。我已经尝试过像mock这样的模拟库,但是它模拟了整个模块,但是失败了。 任何帮助将不胜感激(如果我只嘲笑DateTime.utc_now一切都很好)

注意:测试在很大程度上取决于其他DateTimeDate函数,因此模拟整个模块不是一个很好的选择(我也尝试过此操作,但由于情况非常复杂而失败,我需要在很多测试)

实际测试: 我有两个日期start dateend date作为我要测试的函数的输入。在出于测试目的调用该函数之前,我在当前星期(当前数据到接下来的7天)插入一些数据相关事件。现在,该函数将获取当前日期时间并检查特定的日期(每个记录将告诉它是否适用于星期几以及当前时间范围(要迭代的日期范围->开始日期和结束日期))。 例如,一条记录适用于mon-> 2:12至3:13

2 个答案:

答案 0 :(得分:1)

最适合我的需求的解决方案(简单,有效且符合上述要求)是:

  

定义您自己的功能/服务MyDateTime.utc_now/0并在测试中对其进行模拟。 — Reference

答案 1 :(得分:0)

  

现在该函数将获得当前的datetime并检查特定的日子[...]

这是真正的问题所在。您无缘无故地使函数不纯净。通常,纯度意味着该功能没有副作用,但是根据外部世界盲目更改结果也不是可靠的方法。

也就是说,您应该使此函数接受参数now或类似参数(为简洁起见,可能默认将其设置为now):

- def my_func(param) do
+ def my_func(param, dt \\ nil) do
+   dt = if is_nil(dt), do: DateTime.utc_now(), else: dt

(原始dt \\ DateTime.utc_now()无法正常工作,因为函数头是在编译时进行评估的。)

现在,在您的测试中,您可以根据需要的时间调用此函数。(更重要的是)取决于外部的不相关条件,您的功能不再是黑盒。