Ruby on rails RSpec';s失败,因为它认为ActiveRecord对象不是';不相等

Ruby on rails RSpec';s失败,因为它认为ActiveRecord对象不是';不相等,ruby-on-rails,ruby,rspec,factory-bot,Ruby On Rails,Ruby,Rspec,Factory Bot,非常简单的规范 @post.user.should == @user 即使两个对象除了其对象id之外在各个方面都相同,规范也会失败。如果ActiveRecord对象的id相同,则它们应该相等(=)。正在使用factory_girl创建对象。我已经确认两个对象都不是“.新记录?”。比较@post.user.id和@user.id是有效的 更重要的是,这种行为并不一致。这些测试一直在工作,现在尽管没有任何变化,它们还是失败了 轨道3.1 rspec-2.6 工厂女孩-2.0.5 工厂女孩轨道-1

非常简单的规范

@post.user.should == @user
即使两个对象除了其对象id之外在各个方面都相同,规范也会失败。如果ActiveRecord对象的id相同,则它们应该相等(=)。正在使用factory_girl创建对象。我已经确认两个对象都不是“.新记录?”。比较@post.user.id和@user.id是有效的

更重要的是,这种行为并不一致。这些测试一直在工作,现在尽管没有任何变化,它们还是失败了

  • 轨道3.1
  • rspec-2.6
  • 工厂女孩-2.0.5
  • 工厂女孩轨道-1.1.0
  • jruby 1.6.4(ruby-1.9.2-p136)
  • 窗口7
我通常使用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)

在我的environments/test.rb文件中设置cache_classes=true似乎可以解决这个问题,但我认为这不必要。

由于活动记录的工作方式,这些对象具有不同的对象ID。在你给出的例子中

@post.user.should == @user
@post.user和@user是内存中完全独立的对象。即使它们是同一类的实例,并且具有相同的id字段,它们也永远不会具有相同的object\u id(显然,只要cache\u classes=false)

其他的ORM,比如数据映射器,用一个身份映射来处理这个问题。在Rails3.1中,活动记录中有实验性的身份映射支持,但默认情况下是禁用的


有关更多信息,请参见

,最终这真是太愚蠢了。问题是我在/spec/integration而不是/spec/requests中进行了集成测试。Rspec/Rails只在一组特定的目录中执行加载魔法,但会从所有目录运行所有测试(导致双重加载)。

您在控制台中尝试过吗?此外,你有没有用另一个ruby虚拟机(如MRI)而不是jruby来尝试过?我在使用MRI时也有同样的问题。你如何用FactoryGirl创建它们?我只使用FactoryGirl创建用户。。。“user=Factory(:user)”,位于规范顶部的“before”块内。使用user.post.build(在另一个before块内)创建post。在factories.rb内部,我有一个Factory.define和我的用户属性。(stackoverflow阻止我在评论中的某些地方添加@)你能发布整个规范吗?也许有一些存根正在发生,让事情变得混乱。这不是问题所在。我希望他们的目标是不同的。ActiveRecord覆盖==因此,如果它们具有相同的id属性和类,则应返回True。问题是,虽然类是相同的(“用户”),但类本身有不同的object_id(意味着它们已经加载了两次)