Time warp for functional and unit testing
Add this at the top of test/test_helper.rb (or elsewhere if not using rails):
1 2 # Extend the Time class so that we can offset the time that 'now' 3 # returns. This should allow us to effectively time warp for functional 4 # tests that require limits per hour, what not. 5 class Time #:nodoc: 6 class <<self 7 attr_accessor :testing_offset 8 alias_method :real_now, :now 9 def now 10 real_now - testing_offset 11 end 12 alias_method :new, :now 13 end 14 end 15 Time.testing_offset = 0
Add this method to Test::Unit::TestCase (in the class definition in test_helper.rb):
1 # Time warp to the specified time for the duration of the passed block 2 def pretend_now_is(time) 3 begin 4 Time.testing_offset = Time.now - time 5 yield 6 ensure 7 Time.testing_offset = 0 8 end 9 end
And now you can write time-based tests. For example:
1 2 def test_should_not_allow_more_than_3_requests_in_last_hour_from_same_ip 3 (1..3).each { |n| successful_request } 4 5 start_count = WorkOrderRequest.count 6 post :new, :work_order_request => REQUEST_TEMPLATE 7 assert_response :redirect 8 assert_redirected_to :controller => 'work_order_request', 9 :action => 'limit_exceeded' 10 assert_equal start_count, WorkOrderRequest.count 11 end 12 13 def test_should_not_allow_more_than_10_requests_in_last_24_hours_from_same_ip 14 10.downto(1) do |n| 15 pretend_now_is(n.hours.ago) do 16 successful_request 17 end 18 end 19 20 start_count = WorkOrderRequest.count 21 post :new, :work_order_request => REQUEST_TEMPLATE 22 assert_response :redirect 23 assert_redirected_to :controller => 'work_order_request', 24 :action => 'limit_exceeded' 25 assert_equal start_count, WorkOrderRequest.count 26 end