【发布时间】:2010-08-30 20:16:18
【问题描述】:
我有一些嵌套模型需要比标准accepts_nested_attributes_for 逻辑更多的东西。在这种情况下,子记录必须已经存在并且具有某些其他条件,而不是根据 id 键自动创建或更新子记录,否则会引发错误。
因此,作为其中的一部分,我有一个父模型迭代给定的子属性并在匹配的子记录上调用#update_attributes。
我的问题是如何在父模型的规范中模拟 #update_attributes。我想测试给定属性标识的子记录实际上是接收#update_attributes
我的第一个方法是尝试 mock_model,类似这样(为了清楚起见,不使用实际的模型名称,而是简单地使用“主题”和“孩子”):
before :each do
subject.children = mock_model(Child), mock_model(Child), mock_model(Child)
subject.save!
@expected = subject.children[1]
@input = {:child_id => @expected.id, :value => 'something'}
end
it 'should call #update_attributes on the child with given attributes' do
@expected.should_receive(:update_attributes).
with({:value => 'something'})
subject.merge_children_attributes(@input)
end
但是,您实际上不能持久化模拟模型。出于同样的原因,您也不能使用存根模型。而且我需要持久化记录,因为我在实现中使用了children.find() 或children.all()。 (除非我嘲笑children 关联,考虑到它是主题的一种方法,这似乎不正确)。
然后我去了固定装置。
fixtures :children
before :each do
subject.children = children(:one), children(:two), children(:three)
subject.save!
@expected = subject.children[1]
@input = {:child_id => @expected.id, :value => 'something'}
end
it 'should call #update_attributes on the child with given attributes' do
@expected.should_receive(:update_attributes).
with({:value => 'something'})
subject.merge_children_attributes(@input)
end
这里的问题是预期的匹配记录 (@expected) 永远不会收到 :update_attributes -- 任何东西。
有很多 puts 存在,其原因是当实现调用 children.find() 时,它返回 与规范中的 @expected = subject.children[1] 不同的实例。虽然 :id 属性是相同的。 ActiveRecord 不是身份映射...
那么我该如何编写这个规范才能通过呢?
更新
我确认查看日志确实正在更新正确的记录。所以令人沮丧的是,我似乎无法模拟 :update_attributes,因为在 finds 之间没有维护对象身份。
【问题讨论】:
标签: ruby-on-rails activerecord rspec