【问题标题】:How can I make this Time assertion match perfectly with either Time, Date, or DateTime如何使这个时间断言与时间、日期或日期时间完美匹配
【发布时间】:2016-06-18 15:50:02
【问题描述】:

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

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 等。我怎样才能使测试通过?

【问题讨论】:

  • 看来object.sent_at 正在返回Date,没有时间显示您的“实际”结果。所以我不认为针对Time 对象进行测试是正确的方法。如果你做了assert_equals object.sent_at.to_db, Date.today 有帮助吗?我很想说assert_equals object.sent_at, Date.today 应该足够好,但看来您可能已经尝试过了。

标签: ruby-on-rails datetime minitest


【解决方案1】:

旧但仍然有效...输出显示与 UTC 的比较是 Time.current

此时你可能会使用:

assert_in_delta object.sent_at, Time.current, 1

容忍

【讨论】:

    【解决方案2】:

    使用 Time#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。所以断言失败。 因此,有时测试会通过而其他测试会失败,这取决于它何时开始(以毫秒为单位)。

    更好的解决方案是冻结时间。您可以使用 Timecop 之类的 gem,也可以编写自己的代码,例如(使用 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
    

    【讨论】:

    • 是的。刚遇到同样的问题!感谢时间警察。这是救命稻草。一件事,“存根”是时间的一部分吗?我遇到了问题。我最终改用.freeze
    • #stubs 实际上来自 Mocha(我会修复答案),顺便说一句,这很棒。 Minitest 有一个名为#stub 的方法,这是我回答中的第二个选项
    • 谢谢 :D 我用过 Timecop,它是救命稻草!使用简单,工作完美;)
    • 在第二个示例中,current_time 也可以替换为 Time.now,这样它就可以在任何地方工作。
    【解决方案3】:

    我认为使用Time#to_i 比较时间以秒为单位是最简单的。

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

    【讨论】:

    • 这正是我所需要的!非常感谢。
    • 虽然这是公认的答案,但 Gorodscy 的答案更完整。绝对是使用 Timecop 或存根来确保 Time.now 保持不变以进行比较的好主意。
    【解决方案4】:

    你可以使用Timecopgem: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
    
    

    【讨论】:

      猜你喜欢
      • 2021-12-21
      • 2010-12-21
      • 1970-01-01
      • 1970-01-01
      • 2014-01-29
      • 2011-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多