2014-01-13 73 views
0

我在测试用户之间的聊天内容。我使用的RSpec和FactoryGirl为什么rails中的“where”查询返回不同的对象?

,这不是通过测试:

it "creates a chat if one does not exist" do 
    bob = create(:user, username: "bob") 
    dan = create(:user, username: "dan") 
    new_chat = Chat.create(user_id: @dan.id, chatted_user_id: bob.id) 
    expect(Chat.where("chatted_user_id = ?", bob.id).first).to equal(new_chat) 
end 

失败消息称:

Failure/Error: expect(Chat.where("chatted_user_id = ?", bob.id).first).to equal(new_chat) 

    expected #<Chat:70120833243920> => #<Chat id: 2, user_id: 2, chatted_user_id: 3> 
     got #<Chat:70120833276240> => #<Chat id: 2, user_id: 2, chatted_user_id: 3> 

    Compared using equal?, which compares object identity, 
    but expected and actual are not the same object. Use 
    `expect(actual).to eq(expected)` if you don't care about 
    object identity in this example. 

为什么我的查询返回不同的对象ID?

回答

2

equal检查对象的身份。您正在测试的对象是引用同一记录的两个对象(实例),但实际上它们是从Ruby虚拟机角度看的不同对象。

您应该使用

expect(Chat.where("chatted_user_id = ?", bob.id).first).to eq(new_chat) 

为了更好地理解这个问题,看看下面的例子

2.0.0-p353 :001 > "foo".object_id 
=> 70117320944040 
2.0.0-p353 :002 > "foo".object_id 
=> 70117320962820 

在这里,我创建了两个相同的字符串。它们是相同的,但并不相同,因为它们实际上是两个不同的对象。

2.0.0-p353 :008 > "foo" == "foo" 
=> true 
2.0.0-p353 :009 > "foo".equal? "foo" 
=> false 

这是影响您的测试的相同问题。 equal检查两个对象在object_id级别是否实际相同。但是你真正想知道的是他们是否是同一个记录。

+0

谢谢西蒙娜!那么==和eq一样吗?他们是否只是检查对象的“价值”?另外,你能否提出有关ActiveRecord实例的更多信息? –

+0

是的,'eq'是'=='的RSpec匹配器。 –

相关问题