Replace Timecop With Rails’ Time Helpers in RSpec

Time-sensitive tests can be a pain.

Thankfully, for many years the timecop gem served as a way to “freeze” time and “time travel” during tests, so that any time that elapsed during the running of your tests did not affect the results.

It’s such a good idea that Rails built very similar functionality into Active Support, released in Rails 4.1.

Instead of…

…using timecop in your Rails projects:

Gemfile

group :test do
  gem "timecop"
end

Your tests

describe "some set of tests to mock" do
  before do
    Timecop.freeze(Time.local(1994))
  end

  after do
    Timecop.return
  end

  ### your tests here
end

Use…

…the built-in Rails helpers.

spec/support/time_helpers.rb

RSpec.configure do |config|
  config.include ActiveSupport::Testing::TimeHelpers
end

Your tests

describe "some set of tests to mock" do
  before do
    travel_to Time.local(1994)
  end

  after do
    travel_back
  end

  ### your tests here
end

But why?

Freezing time can be useful if you ever find yourself testing times or dates used inside your app. As your tests run, real time elapses and this can sometimes lead to tests where the expected result and actual value can be seconds apart.

Given that Rails has included these helpers, there’s no reason to use timecop as you’d be adding a dependency for functionality that’s already been provided by the framework.

Why not?

If you’re outside of a Rails application, perhaps writing a gem or using another framework, you won’t have access to these helpers without manually including Active Support, so timecop is still a brilliant choice.

Even inside a Rails application you might choose to use the timecop gem as it has some slightly enhanced functionality over the Active Support helpers.

It contains methods to change the speed at which time passes, which my be useful if your application needs something to happen as time passes. For example, if you need to check whether an email is sent out within an hour, you don’t want to sit there waiting for the actual time to pass.

Last updated on January 27th, 2019