ActiveRecord :: Associations :: CollectionProxy返回1的计数,但是存在吗?在RSpec测试中是假的

时间:2016-03-31 21:43:11

标签: ruby-on-rails ruby rspec

我正在使用RSpec进行如下测试,我的测试告诉我,我为一次测试创建了ActiveRecord::CollectionProxycount的{​​{1}}个对象,但随后返回present?每个下面的另一个测试都是假的。请注意:child是在:child_link after_create回调中创建的。

let(:link) { create(:child_link) }

it 'should have a child with ancestors class of X' do
  expect(link.child.ancestors.class).to be Stake::ActiveRecord_Associations_CollectionProxy
end
=> PASSES

it 'should have a child with ancestors (1)' do
  expect(link.child.ancestors.count).to eq(1)
end
=> PASSES

it 'should have a child with ancestors present' do
  expect(link.child.ancestors.present?).to be true
end
=> FAILS

为什么这个测试失败了? RSpec告诉我它返回false,不是真的。没有错误。

这是我的工厂:

factory :kin_link do
  group
  stake
  visible true

  factory :child_link, :class => ChildLink do
  end
end

以下是我的协会:

class KinLink < ActiveRecord::Base
  belongs_to :stake, foreign_key: 'feather_id'
  belongs_to :group, foreign_key: 'tip_group_id'
end

class ChildLink < KinLink
  belongs_to :child, class_name: 'Stake', foreign_key: 'tip_id'

class AncestorLink < KinLink
  belongs_to :ancestor, class_name: 'Stake', foreign_key: 'tip_id'
end

class Stake < ActiveRecord::Base

  has_many :kin_links, foreign_key: 'feather_id'

  has_many :child_links, foreign_key: 'feather_id'
  has_many :children, through: :child_links

  has_many :child_links, foreign_key: 'feather_id'
  has_many :children, through: :child_links

  has_many :ancestor_links, foreign_key: 'feather_id'
  has_many :ancestors, through: :ancestor_links

当我这样做时,测试通过:

it 'should pass if I reload the :child_link object' do
  link2 = ChildLink.find(link.id)
  expect(link2.child.ancestors).to be_present
=> PASSES

或者这个:

it 'should pass if I reload the :child_link object' do
  expect(link.child.reload.ancestors).to be_present
end
=> PASSES

是否会以某种方式缓存关联,并且需要在ChildLink发生after_create后重新加载?

在我的控制台沙盒中玩游戏似乎证实了这一点:如果我使用has_many :through然后在结果上调用Stake.find,我可以让ancestors关联生效,但如果我致电child_link.child.ancestors

child_link = FactoryGirl.create(:child_link) 
=> #<ChildLink id: 86...
child_link.child
=> #<Stake id: 84... 
child_link.child.ancestors
=> #<ActiveRecord::Associations::CollectionProxy []>          
Stake.find(84).ancestors
=> #<ActiveRecord::Associations::CollectionProxy [#<Stake id: 83...

根据评论编辑,包括我另外尝试的内容:

  • 使用let语句代替before(:each)
  • 每次使用rake db:test:prepare后单独测试每个。相同的结果。

1 个答案:

答案 0 :(得分:0)

由于child而在after_create回调中创建的create(:child_link) Stake对象正在运行self.ancestors查询(在另一个回调中)。我不知道像这样的查询是缓存的。感谢评论中的每个人指出我正确的方向。