我怎样才能使这个时间断言与时间、日期或日期时间完美匹配

How can I make this Time assertion match perfectly with either Time, Date, or DateTime

我在测试中有一个如下所示的断言:

assert_equals object.sent_at, Time.now

当我 运行 这个测试时,我不断收到如下所示的错误

--- expected +++ actual @@ -1 +1 @@ -Fri, 04 Mar 2016 18:57:47 UTC +00:00 +Fri, 04 Mar 2016

我尝试了一些组合来使这个测试通过。

我的实际代码用 Time.now 更新了 sent_at 值,但它的格式并不完美。它很接近但不足以通过。我怎样才能通过这个测试。

以下是我在断言中尝试过的一些组合:

Time.now.utc Date.today Time.now

和很多 to_timeto_datetime 等。我怎样才能通过测试?

我觉得用Time#to_i来比较时间秒数是最简单的。

assert_equals object.sent_at.to_i, Time.now.to_i # seconds

使用时间#to_i 不是最佳解决方案。如果您 运行 的任务需要超过一秒,比较就会失败。即使您的任务足够快,此比较也会失败:

time = Time.now # 2018-04-18 3:00:00.990
# after 20ms
assert_equal Time.now.to_i, time.to_i # Fails

Time.now 会是 2018-04-18 3:00:01.010 而 to_i 会给你 2018-04-18 3:00:01 时间是 2018-04-18 3:00:00.990 和 to_i:2018-04-18 3:00:00.所以断言失败了。 因此,有时测试会通过而其他测试会失败,这取决于它何时开始(以毫秒为单位)。

更好的解决办法是冻结时间。您可以使用 gem 之类的 Timecop 或编写您自己的代码,例如(使用 MiniTest):

current_time = Time.now
# You need Mocha gem to use #stubs
Time.stubs(:now).returns(current_time)

也可以用block,这样block之后时钟就恢复正常了

# For this you don't need Mocha
Time.stub :now, current_time do   # stub goes away once the block is done
  assert your_task
end

旧但仍然有效...输出显示比较是针对 UTC,即 Time.current

此时你可能会使用:

assert_in_delta object.sent_at, Time.current, 1

容忍<1秒的差异

您可以使用 Timecop gem: https://github.com/travisjeffery/timecop

def test
  Timecop.freeze do # Freeze current time
    Time.now # some value
    ...
    Time.now # The same value as previous
  end
end