Dev

Rspec: Natively control Time with Rails

Profil Picture

Guillaume Briday

1 minute

You can natively control Time in your specs with Rails.

You don't need additional gems like the really good Timecop. Rails has a built-in mechanism to do exactly the same thing.

How to use it?

Include the ActiveSupport::Testing::TimeHelpers module in your spec/rails_helper.rb config file.

# spec/rails_helper.rb

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

Now you can use it in your hooks to change the time in all your tests:

RSpec.describe 'Post' do
  before do
    travel_to Time.new(2023, 12, 4, 16, 30) # Mon, 04 Dec 2023 16:30:00

    # Now, Time.now (and all Time or Date methods), will always return `Time.new(2023, 12, 4, 16, 30)`.
    # Here, Time.current.yesterday will return Sun, 03 Dev 2023 16:30:00.
  end
end

Thanks to the #after_teardown method, you don't need to use the around hook:

# ❌ Don't do this.
RSpec.describe 'Post' do
  around do |test|
    travel_to Time.new(1994) do
      test.run
    end
  end
end

# ✅ Do
RSpec.describe 'Post' do
  before do
    travel_to Time.new(1994)
  end
end

You can also use it directly in your it:

RSpec.describe 'Post' do
  let(:post) { create(:post, published_on: Date.new(2021, 5, 14)) }

  it 'works' do
    travel_to Date.new(2020) do # Not published yet in 2020
      expect(post.published?).to be(false)
    end

    # But published now because we are after May 14, 2021
    expect(post.published?).to be(true)
  end
end

It's really handy when you when to predict results and not rely on current time.

Check out the documentation for more information: ActiveSupport::Testing::TimeHelpers.

Simplify your time tracking with Timecop

Timecop is a time tracking app that brings simplicity in your day to day life.

Timecop projects