包含協助您測試時間推移的幫手。
執行個體公開方法
after_teardown() 連結
來源:顯示 | 在 GitHub 上
# File activesupport/lib/active_support/testing/time_helpers.rb, line 69 def after_teardown travel_back super end
freeze_time(with_usec: false, &block) 連結
使用 Time.now
呼叫 travel_to
。轉發選用的 with_usec
引數。
Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
freeze_time
sleep(1)
Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
此方法也接受區塊,此區塊將在區塊結束時將目前時間返回至其原始狀態
Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
freeze_time do
sleep(1)
User.create.created_at # => Sun, 09 Jul 2017 15:34:49 EST -05:00
end
Time.current # => Sun, 09 Jul 2017 15:34:50 EST -05:00
來源:顯示 | 在 GitHub 上
# File activesupport/lib/active_support/testing/time_helpers.rb, line 257 def freeze_time(with_usec: false, &block) travel_to Time.now, with_usec: with_usec, &block end
travel(duration, with_usec: false, &block) 連結
將目前時間改為透過建立 Time.now
、Date.today
與 DateTime.now
替身來取得的往後或往前的特定時間差異。這些替身會在測試結束時自動移除。
請注意,除非 with_usec
引數設定為 true
,否則結果時間的毫秒將會設定為 0,以防止 MySQL(會進行捨入而非向下取整,導致差一秒的誤差)等外部服務產生捨入誤差。
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
travel 1.day
Time.current # => Sun, 10 Nov 2013 15:34:49 EST -05:00
Date.current # => Sun, 10 Nov 2013
DateTime.current # => Sun, 10 Nov 2013 15:34:49 -0500
此方法也接受區塊,此區塊將在區塊結束時將目前時間返回至其原始狀態
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
travel 1.day do
User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00
end
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
來源:顯示 | 在 GitHub 上
# File activesupport/lib/active_support/testing/time_helpers.rb, line 97 def travel(duration, with_usec: false, &block) travel_to Time.now + duration, with_usec: with_usec, &block end
travel_back() 連結
透過移除 travel
、travel_to
與 freeze_time
所加入的替身,將目前時間返回至其原始狀態。
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
travel_back
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
此方法也接受區塊,此區塊會在區塊結束時帶回這些替身
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
travel_back do
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
end
Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
來源:顯示 | 在 GitHub 上
# File activesupport/lib/active_support/testing/time_helpers.rb, line 231 def travel_back stubbed_time = Time.current if block_given? && simple_stubs.stubbed? simple_stubs.unstub_all! yield if block_given? ensure travel_to stubbed_time if stubbed_time end
travel_to(date_or_time, with_usec: false) 連結
透過建立 Time.now
、Time.new
、Date.today
與 DateTime.now
替身,將目前時間變更為特定的時間,令其回傳傳入此方法的時間或日期。這些替身會在測試結束時自動移除。
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
Date.current # => Wed, 24 Nov 2004
DateTime.current # => Wed, 24 Nov 2004 01:04:44 -0500
日期會取為其在應用程式時區中的那一日開始的當天時間戳記。Time.current
會回傳此時間戳記,而 Time.now
會回傳其在系統時區中的等價時間戳記。類似地,Date.current
會回傳一個等於引數的日期,而 Date.today
會回傳根據 Time.now
的日期,此日期可能不同。(請注意,在較少需要處理 Time.now
或 Date.today
的情況下,請務必使用 Time.current
及 Date.current
來尊重應用程式的時區。)
注意,傳遞的時間的微秒會設為 0,以避免與 MySQL 這樣的外部服務產生四捨五入錯誤(會四捨五入而非無條件捨去,導致誤差在一秒內),除非 with_usec
參數設定為 true
。
此方法也接受區塊,此區塊將在區塊結束時將目前時間返回至其原始狀態
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
travel_to Time.zone.local(2004, 11, 24, 1, 4, 44) do
Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
end
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
# File activesupport/lib/active_support/testing/time_helpers.rb, line 133 def travel_to(date_or_time, with_usec: false) if block_given? && in_block travel_to_nested_block_call = <<~MSG Calling `travel_to` with a block, when we have previously already made a call to `travel_to`, can lead to confusing time stubbing. Instead of: travel_to 2.days.from_now do # 2 days from today travel_to 3.days.from_now do # 5 days from today end end preferred way to achieve above is: travel 2.days do # 2 days from today end travel 5.days do # 5 days from today end MSG raise travel_to_nested_block_call end if date_or_time.is_a?(Date) && !date_or_time.is_a?(DateTime) now = date_or_time.midnight.to_time elsif date_or_time.is_a?(String) now = Time.zone.parse(date_or_time) else now = date_or_time now = now.to_time unless now.is_a?(Time) end now = now.change(usec: 0) unless with_usec # +now+ must be in local system timezone, because +Time.at(now)+ # and +now.to_date+ (see stubs below) will use +now+'s timezone too! now = now.getlocal stubs = simple_stubs stubbed_time = Time.now if stubs.stubbing(Time, :now) stubs.stub_object(Time, :now) { at(now) } stubs.stub_object(Time, :new) do |*args, **options| if args.empty? && options.empty? at(now) else stub = stubs.stubbing(Time, :new) Time.send(stub.original_method, *args, **options) end end stubs.stub_object(Date, :today) { jd(now.to_date.jd) } stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) } if block_given? begin self.in_block = true yield ensure if stubbed_time travel_to stubbed_time else travel_back end self.in_block = false end end end