How to fake Time.now?

前端 未结 14 1134
不知归路
不知归路 2020-12-02 11:47

What\'s the best way to set Time.now for the purpose of testing time-sensitive methods in a unit test?

14条回答
  •  旧巷少年郎
    2020-12-02 12:42

    The recently-released Test::Redef makes this and other fakery easy, even without restructuring the code in a dependency-injection style (especially helpful if you're using other peoples' code.)

    fake_time = Time.at(12345) # ~3:30pm UTC Jan 1 1970
    Test::Redef.rd 'Time.now' => proc { fake_time } do
       assert_equal 12345, Time.now.to_i
    end
    

    However, be careful of other ways to obtain time that this will not fake out (Date.new, a compiled extension that makes its own system call, interfaces to things like external database servers which know current timestamps, etc.) It sounds like the Timecop library above might overcome these limitations.

    Other great uses include testing things like "what happens when I'm trying to use this friendly http client but it decides to raise this an exception instead of returning me a string?" without actually setting up the network conditions which lead to that exception (which may be tricky). It also lets you check the arguments to redef'd functions.

提交回复
热议问题