One thing you need to know about Time testing in Rails

daviidy

David

Posted on November 28, 2024

One thing you need to know about Time testing in Rails

Let's say for example that you have an Event model with a start_time and end_time attributes.
We also have an override method on start_time to default it from end_time.

class Event < ApplicationRecord
  def start_time
    super || end_time
  end
end
Enter fullscreen mode Exit fullscreen mode

Consider this simple RSpec test:

it 'compares times correctly' do
  expect(Event.new(end_time: Time.now).start_time).to eq(Time.now)
end
Enter fullscreen mode Exit fullscreen mode

This test fails. Why? You got it, it's because there are two different moments in time.
One way to fix it is to use variables. Like this:

it 'compares times correctly' do
  current_time = Time.now
  expect(Event.new(end_time: current_time).start_time).to eq(current_time)
end
Enter fullscreen mode Exit fullscreen mode

But let's dig deeper. Let's say we have this:

When we debug:

current_time = Time.now
print current_time                    # => 2024-11-28 12:06:25 -0600
print Event.new(end_time: current_time).start_time  # => 2024-11-28 18:06:25 UTC
Enter fullscreen mode Exit fullscreen mode

This spec passes even though both time are different. Why?
Here is why: when RSpec compares times with eq, it compares the actual moments in time, not their string representations or timezone formats.
So 2024-11-28 12:06:25 -0600and 2024-11-28 18:06:25 UTC will be equal.

The Ultimate Lesson

When working with time in Rails:

  1. Remember ActiveRecord converts to UTC automatically
  2. Store time instances in variables for comparisons
  3. Times are equal if they represent the same moment, regardless of timezone

Any thoughts or feedback on this?
Let me know in the comments.

💖 💪 🙅 🚩
daviidy
David

Posted on November 28, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related