Fixing Rspec tests involving timestamps on CircleCI.

In one of my projects I had the following test case which depended on the timestamp of the created record.

Pretty simple thing at first sight, just making sure that we set the confirmed_at value when a user confirm his/her account.

it "updates confirmed_at and removes confirmation token" do
  confirm_account

  expect(user.confirmation_token).to be_nil
  expect(user.confirmed_at).to eq(Time.zone.now)
end

Now I bumped into the classic problem -  this works on my machine but fails in the CircleCI.

So as usual, google fu to the rescue.

Courtesy to this stackoverflow post, I figured out this:

Time.now actually has different precision on OS X and Linux machines. I would suppose that you will get the exact same result on other Linux hosts, but all OS X hosts will give you the result without rounding.

Solutions.

  1. Use Timecop gem.
it "updates confirmed_at and removes confirmation token" do
  Timecop.freeze(Time.zone.now) do
    confirm_account

    expect(user.confirmation_token).to be_nil
    expect(user.confirmed_at).to eq(Time.zone.now)
  end
end

OR

2. Rspec be_within matcher

it "updates confirmed_at and removes confirmation token" do
  confirm_account

  expect(user.confirmation_token).to be_nil
  expect(user.confirmed_at).to be_within(1).of(Time.now)
end

References:

https://stackoverflow.com/questions/30139038/circleci-error-with-a-spec-involving-timestamps

https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/built-in-matchers/be-within-matcher

https://blog.eq8.eu/article/rspec-be-within-matcher.html