Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rails rspec testing updating attribute on model

I have a very simple model called Reminder with a boolean attribute of verified and I want to test my method update_verified which simply sets the attribute verified to true. I'm using rspec and factory girl.

# reminder.rb
  def update_verified
    self.update(verified: true)
  end 

# reminder_spec.rb
  describe "#update_verified" do
    it "should mark the reminder.verified to true" do
      reminder = build(:reminder, verified: false)
      reminder.update_verified

      expect(reminder.verified).to eq(true)
    end
  end

For some reason, when I run the test, the new value of true for the attribute verified is not being persisted. However, when I run the method in console, it works fine. Thoughts?

  1) Reminder#update_verified should mark the reminder.verified to true
     Failure/Error: expect(reminder.verified).to eq(true)

       expected: true
            got: false

       (compared using ==)
     # ./spec/models/reminder_spec.rb:46:in `block (3 levels) in <top (required)>'

Finished in 0.19193 seconds (files took 7.07 seconds to load)
like image 467
thedanotto Avatar asked Jul 02 '16 22:07

thedanotto


3 Answers

You just need to reload your object:

expect(reminder.reload.verified).to eq(true)
like image 110
Anthony Avatar answered Sep 18 '22 21:09

Anthony


I found this helpful to check if the method saves changes to an object in the database:

expect { reminder.update_verified }.to change(reminder, :updated_at)

Explanation

Calling self.update(verified: true) does not only update the verified-column, but also the updated_at-column. We can then check for changes in the updated_at-column to verify that changes to the object has been saved.

like image 32
Andreas Avatar answered Sep 17 '22 21:09

Andreas


This works for me

expect {
  do_something
  reminder.reload
}.to change(reminder, :verified)
like image 21
Frank Fang Avatar answered Sep 16 '22 21:09

Frank Fang