How to fake Time.now?

2019-01-10 12:04发布

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

14条回答
虎瘦雄心在
2楼-- · 2019-01-10 12:43

Do the time-warp

time-warp is a library that does what you want. It gives you a method that takes a time and a block and anything that happens in the block uses the faked time.

pretend_now_is(2000,"jan",1,0) do
  Time.now
end
查看更多
Bombasti
3楼-- · 2019-01-10 12:44

I allways extract Time.now into a separate method that I turn into attr_accessor in the mock.

查看更多
在下西门庆
4楼-- · 2019-01-10 12:46

i just have this in my test file:

   def time_right_now
      current_time = Time.parse("07/09/10 14:20")
      current_time = convert_time_to_utc(current_date)
      return current_time
    end

and in my Time_helper.rb file i have a

  def time_right_now
    current_time= Time.new
    return current_time
  end

so when testing the time_right_now is overwritten to use what ever time you want it to be.

查看更多
Juvenile、少年°
5楼-- · 2019-01-10 12:46
干净又极端
6楼-- · 2019-01-10 12:50

Don't forget that Time is merely a constant that refers to a class object. If you're willing to cause a warning, you can always do

real_time_class = Time
Time = FakeTimeClass
# run test
Time = real_time_class
查看更多
乱世女痞
7楼-- · 2019-01-10 12:51

Personally I prefer to make the clock injectable, like so:

def hello(clock=Time)
  puts "the time is now: #{clock.now}"
end

Or:

class MyClass
  attr_writer :clock

  def initialize
    @clock = Time
  end

  def hello
    puts "the time is now: #{@clock.now}"
  end
end

However, many prefer to use a mocking/stubbing library. In RSpec/flexmock you can use:

Time.stub!(:now).and_return(Time.mktime(1970,1,1))

Or in Mocha:

Time.stubs(:now).returns(Time.mktime(1970,1,1))
查看更多
登录 后发表回答