mc9
mc9

Reputation: 6349

RSpec eq matcher returns failure when two things are equal

In my controller test, I am testing the correct value is assigned to an instance variable.

When I do

expect(assigns(:conversations)).to eq @user_inbox

RSpec tells me:

 Failure/Error: expect(assigns(:conversations)).to eq @user_inbox

   expected: #<ActiveRecord::Relation [#<Mailboxer::Conversation id: 4, subject: "Dude, what up?", created_at: "2014-10-21 08:43:50", updated_at: "2014-10-21 08:43:50">]>
        got: #<ActiveRecord::Relation [#<Mailboxer::Conversation id: 4, subject: "Dude, what up?", created_at: "2014-10-21 08:43:50", updated_at: "2014-10-21 08:43:50">]>

   (compared using ==)

   Diff:

I see that there is no difference between the expected and the actual. I would like to know what is causing this test to fail.

Upvotes: 2

Views: 2550

Answers (3)

Frederick Cheung
Frederick Cheung

Reputation: 84114

ActiveRecord::Relation compares based on the actual relation, not the result set. For example,

User.where(:id => 123) == User.where(:email => "[email protected]")

will return false, even the query results are both the same, since the actual queries are different.

I suspect that you care much more about the query results rather than how it was composed, in which case you can use to_a to convert the relation to an array of active record objects. Note that Active Record defines equality based only on the value of the id attribute (with a special case for unsaved objects).

Upvotes: 4

Montells
Montells

Reputation: 6679

Maybe you should change the test strategy.

When your test is hard to write your code is wrong or your test strategy is wrong. I recommend you no test query result in the controller's test.

you should mock your query result

describe 'GET user conversations' do
  before do
    your_user.stub(:conversations).and_return "foo bar"       
  end
  it 'assigns the conversations of the user' do
    get :user_conversation
    expect(assigns(:conversations)).to eq your_user.conversations
  end
end

or you should test that some_collaborator.should_receive(:some_methods)

describe 'GET user conversations' do
  before do
    some_collaborator.stub(:conversations)
  end
  it 'assigns the conversations of the user' do
    some_collaborator.should_receive(:conversations)
    get :user_conversation
  end
end

Upvotes: 0

kepes
kepes

Reputation: 800

Yes, because this is two ActiveRecord::Relation object. Your instance variable is the first one and you create another one called conversations

You should test the number of rows or other property with something like this:

expect(assigns(:conversations).count).to eq @user_inbox.count

Upvotes: 0

Related Questions