Ошибка RSpec, потому что он считает, что объекты ActiveRecord не равны - PullRequest
4 голосов
/ 16 сентября 2011

Очень простая спецификация ...

@post.user.should == @user

Спецификация не работает, даже если оба объекта идентичны во всех отношениях, кроме их object_id.Объекты ActiveRecord должны быть равны (==), если их идентификаторы одинаковы.Объекты создаются с использованием factory_girl.Я подтвердил, что ни один из объектов не является ".new_record?".Сравнение @ post.user.id и @ user.id работает.

Более того, поведение не согласовано.Эти тесты работали, и теперь они не проходят, несмотря на все изменения.

  • Rails 3.1
  • rspec-2.6
  • factory_girl-2.0.5
  • factory_girl_rails-1.1.0
  • jruby 1.6.4 (ruby-1.9.2-p136)
  • windows7

Обычно я использую 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)

Настройка cache_classes =true в моем файле environment / test.rb, похоже, это исправлено, но я не думаю, что это необходимо.

Ответы [ 2 ]

1 голос
/ 22 сентября 2011

Это оказалось очень глупо.Проблема заключалась в том, что у меня были свои интеграционные тесты в / spec / интеграции вместо / спецификации / запросов.Rspec / Rails выполнял свою магию загрузки только в определенном наборе каталогов, но запускал все тесты из всех каталогов (вызывая двойную загрузку).

0 голосов
/ 20 сентября 2011

Эти объекты имеют разные object_ids из-за способа работы активной записи. В приведенном вами примере

@post.user.should == @user

@post.user и @user - это совершенно разные объекты в памяти. Даже если они являются экземплярами одного и того же класса и имеют одинаковое поле идентификатора, они никогда не будут иметь одинаковый object_id (очевидно, до тех пор, пока cache_classes = false).

Другие ORM, такие как преобразователь данных, обрабатывают это с помощью карты идентификации. В Rails 3.1 имеется экспериментальная поддержка карт идентификации в активной записи, но она по умолчанию отключена.

См. identity_map.rb для получения дополнительной информации

...