railsuser400
railsuser400

Reputation: 1023

Why must I reload instance variables in rspec specs?

I have a spec like the following:

describe 'toggle_approval' do
  before(:each) do
    @comment = Comment.make(id: 55, approved: false)
  end

  it "toggles the visibility of the discussion" do
    post :toggle_approval, id: 55
    #@comment.reload
    @comment.approved.should be_true
  end
end

This spec will fail unless I uncomment the line that reloads the comment. Why is rails not reloading this for me?

Upvotes: 4

Views: 3396

Answers (2)

dimitry_n
dimitry_n

Reputation: 3019

To add to Marek's answer, you can also call .reload inline like so:

it "toggles the visibility of the discussion" do
  post :toggle_approval, id: 55
  @comment.reload.approved.should be_true
end

or use something like this:

it "toggles the visibility of the discussion" do
  expect {
    post :toggle_approval, id: 55
  }.to change {
    @comment.reload.approved
  }.from(...)
   .to(...)
end

Upvotes: 1

Marek Lipka
Marek Lipka

Reputation: 51181

Because you don't tell it to reload your record. Comment instance in your controller is created independently from @comment variable set in your specs. So if you don't use reload explicitly, it won't be reloaded. If you want your Comment instance in controller to be the same instance than in spec, you can do some stubbing:

Comment.should_receive(:find).with(@comment.id) { @comment }

Upvotes: 5

Related Questions