跳至内容 跳至搜索

包含帮助您测试时间流逝的助手。

方法
A
F
T
U

实例公共方法

after_teardown()

# File activesupport/lib/active_support/testing/time_helpers.rb, line 69
def after_teardown
  travel_back
  super
end

freeze_time(with_usec: false, &block)

调用 travel_to 并使用 Time.now。转发可选的 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
# 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.nowDate.todayDateTime.now,将当前时间更改为未来或过去某个时间差的时间。存根会在测试结束时自动删除。

请注意,除非 with_usec 参数设置为 true,否则生成时间的 usec 将设置为 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
# 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()

通过删除 traveltravel_tofreeze_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
也作为别名:unfreeze_time
# 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.nowTime.newDate.todayDateTime.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.nowDate.today,请始终使用 Time.currentDate.current。)

请注意,除非 with_usec 参数设置为 true,否则传递的时间的 usec 将设置为 0,以防止与外部服务(如 MySQL)出现舍入错误(它将四舍五入而不是向下取整,从而导致误差)。

此方法还接受一个块,该块将在块结束时将当前时间恢复到其原始状态。

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

unfreeze_time()

别名:travel_back