One thing you need to know about Time testing in Rails
David
Posted on November 28, 2024
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 -0600
and 2024-11-28 18:06:25 UTC
will be equal.
The Ultimate Lesson
When working with time in Rails:
- Remember ActiveRecord converts to UTC automatically
- Store time instances in variables for comparisons
- Times are equal if they represent the same moment, regardless of timezone
Any thoughts or feedback on this?
Let me know in the comments.
Posted on November 28, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.