One thing you need to know about Time testing in Rails

Today

Read on Dev.to →

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

Consider this simple RSpec test:

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

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

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

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.

Comments (0)

Add Comment