Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Make Time "Stand Still" In Ruby

DZone's Guide to

Make Time "Stand Still" In Ruby

·
Free Resource
When writing tests, it's sometimes difficult to test results of methods that use current time. Two calls to Time.now can give different results and cause test failures. Here is some code that lets you execute a block during which Time.now will return a consistent value:


class Time

  # this code adds a Time.freeze method to make time "stand still"
  # during execution of a block. This can be helpful during testing of
  # methods that depend on Time.new or Time.now
  #
  # Example:
  #
  #   Time.freeze do
  #      puts Time.new.to_f
  #      # ... do stuff; real time passes
  #      puts Time.new.to_f     # outputs same time as above
  #   end
  #   # ... time returns to normal
  #
  # An optional Time object may be passed to freeze to a specific time:
  #
  #   Time.freeze(Time.at(2007, 11, 15)) do
  #      # ...
  #   end
  #
  # While inside the block, Time.frozen? will return true

  class << self

    def now
      @time || orig_new
    end

    alias_method :orig_freeze, :freeze
    alias_method :orig_new, :new
    alias_method :new, :now

    # makes time "stand still" during execution of a block. if no time is
    # supplied, the current time is used. While in the block, Time.new and
    # Time.now will always return the "frozen" value.
    def freeze(time = nil)
      raise "A block is required" unless block_given?
      begin
        prev = @time
        @time = time || now
        yield
      ensure
        @time = prev
      end
    end

    def frozen?
      !@time.nil?
    end

  end
end
Topics:

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}