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.
timecop in your Rails projects:
group :test do gem "timecop" end
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
…the built-in Rails helpers.
RSpec.configure do |config| config.include ActiveSupport::Testing::TimeHelpers end
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
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.
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 by @andycroll
An email newsletter, with one Ruby/Rails technique delivered with a ‘why?’ and a ‘how?’ every two weeks. It’s deliberately brief, focussed & opinionated.