非常简单的规范......
@post.user.should == @user
Spec失败,即使两个对象除了object_id之外在各方面都相同。如果它们的id相同,则ActiveRecord对象应该等于(==)。使用factory_girl创建对象。我已经确认这两个对象都不是“.new_record?”。比较@ post.user.id和@ user.id有效。
更多的是行为不一致。这些测试正在进行,现在尽管没有变化,但它们仍然失败。
我通常使用spork,但这也没有spork。
更多细节:
在ActiveRecord :: Base
中,有问题的代码行似乎如下def ==(comparison_object)
super ||
comparison_object.instance_of?(self.class) &&
id.present? &&
comparison_object.id == id
end
具体来说,“instance_of?”检查失败的时候不应该。我检查了两个对象的类层次结构。但是,当我检查每个对象的class.id时,它们并不相同。
此外,行为取决于我运行的命令......
jruby -S bundle exec rspec spec (FAILS)
jruby -S bundle exec rspec spec\models (PASSES)
jruby -S bundle exec rspec spec\models\post_spec.rb (PASSES)
在我的environment / test.rb文件中设置cache_classes = true似乎解决了这个问题,但我不认为这是必要的。
答案 0 :(得分:1)
这最终真的很傻。问题是我在/ spec / integration中进行了集成测试而不是/ spec / requests。 Rspec / Rails只在一组特定的目录中执行加载魔术,但会从所有目录运行所有测试(导致双重加载)。
答案 1 :(得分:0)
由于活动记录的工作方式,这些对象具有不同的object_id。在你给出的例子中
@post.user.should == @user
@ post.user和@user是内存中完全独立的对象。即使它们是同一个类的实例,并且它们具有相同的id字段,它们也永远不会具有相同的object_id(显然只要cache_classes = false)。
其他ORM(例如数据映射器)使用身份映射处理此问题。在Rails 3.1中,活动记录中有实验性身份映射支持,但默认情况下禁用它。
有关详细信息,请参阅identity_map.rb