0

I have a method like this:

class Company < ActiveRecord::Base
  before_save :update_read_status  
  def update_read_status
    if read_changed?
      column = read ? :read_at : :unread_at
      self[column] = Time.zone.now
    end
  end
end

And I want to test the code with this RSpec:

  context "#update_read_status" do
  before{ company.update_attributes(read_at: 2.months.ago) }
    context "when read become true" do
      it "read_at be current time" do
        expect{ company.update_attributes(read: true) }.to change{ company.read_at }.from(2.months.ago).to(Time.current)
      end
    end
  end

I know this spec fails because the time are changing during the test, but how can I compare time with change matcher?

I found a similar question Trouble comparing time with RSpec , but the way with to_s method or be_within matcher is not available option in my case.

Community
  • 1
  • 1
ironsand
  • 14,329
  • 17
  • 83
  • 176

1 Answers1

0

Use to_i method to get time in seconds since Epoch and build the new Time with Time.at using those seconds as parameters. This will ignore that milliseconds who are messing with the test.

expect{ company.update_attributes(read: true) }
.to change{ Time.at(company.read_at.to_i) }
.from(2.months.ago).to(Time.at(Time.current.to_i))
Guilherme Carlos
  • 1,093
  • 1
  • 15
  • 29
  • I could pass the test by changing `2.months.ago` to `Time.new(2014,1,1)`. It didn't occurred to use `Ttime.at`. Thanks! – ironsand Mar 04 '15 at 06:19