Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make this Time assertion match perfectly with either Time, Date, or DateTime

I have an assertion in a test that looks like this:

assert_equals object.sent_at, Time.now

When I run this test, I keep getting an error that looks like this

--- expected +++ actual @@ -1 +1 @@ -Fri, 04 Mar 2016 18:57:47 UTC +00:00 +Fri, 04 Mar 2016

I've tried a few combinations to make this test pass.

My actual code updates the sent_at value with a Time.now but its not quite in the perfect format. It is close but not enough to pass. How can I make this test pass.

Here are some combinations I've tried in my assertions:

Time.now.utc Date.today Time.now

and a lot of to_time , to_datetime etc. How can I make the test pass?

like image 801
Dan Rubio Avatar asked Mar 04 '16 19:03

Dan Rubio


3 Answers

Old but still valid... The output shows that the comparison is against UTC which would be Time.current

At this time you would probably use:

assert_in_delta object.sent_at, Time.current, 1

To tolerate <1 second difference

like image 124
estani Avatar answered Nov 17 '22 19:11

estani


Using Time#to_i isn't the best solution. If the task you are running takes more than a second the comparison would fail. Even if your task is fast enough, this comparison would fail:

time = Time.now # 2018-04-18 3:00:00.990
# after 20ms
assert_equal Time.now.to_i, time.to_i # Fails

Time.now would be 2018-04-18 3:00:01.010 and to_i would give you 2018-04-18 3:00:01 and time was 2018-04-18 3:00:00.990 and to_i: 2018-04-18 3:00:00. So the assert fails. So, sometimes the test would pass and others would fail, depending on when (in miliseconds) it starts.

The better solution is to freeze the Time. You could use a gem like Timecop or write your own code, like (using MiniTest):

current_time = Time.now
# You need Mocha gem to use #stubs
Time.stubs(:now).returns(current_time)

You can also use a block, so that after the block the clock is back to normal

# For this you don't need Mocha
Time.stub :now, current_time do   # stub goes away once the block is done
  assert your_task
end
like image 31
Gorodscy Fernando Avatar answered Nov 17 '22 20:11

Gorodscy Fernando


I think it is easiest to use Time#to_i to compare the time in seconds.

assert_equals object.sent_at.to_i, Time.now.to_i # seconds

like image 4
Jack Collins Avatar answered Nov 17 '22 20:11

Jack Collins