我对receive_message_chain rspec 3.6有一个奇怪的问题
allow_any_instance_of(Order).to receive_message_chain('line_items.find')
{LineItem.first}
当我执行order.line_items而不是返回一个集合时,它返回一个<Double (anonymous)>
对象,这不是我想要的。
有什么建议吗?
答案 0 :(得分:1)
当您告诉RSpec在特定对象上设置receive_message_chain('line_items.find')
时,它需要设置正确的存根以使链工作。
首先,RSpec在对象上存根方法line_items
。接下来它需要存根方法find
,但是这个方法需要在方法line_items
的返回值上存根。由于我们使用了该方法,因此RSpec需要提供一些返回值,这可以是存根的目标。
因此,RSpec将方法line_items
的返回值设置为具有方法find
存根的匿名双精度。因此,一旦您将receive_message_chain
设置为'line_items.find'
,则在调用line_items
时,对象将始终返回匿名双精度。由于您使用allow_any_instance_of
,这意味着方法line_items
现在存在于Order
的所有实例上。
如果可能的话,我建议考虑尝试从您的规范中删除allow_any_instance_of
和receive_message_chain
的用法,因为如果您真的无法更改设计,它们实际上是在规范中使用的快捷方式你的代码https://relishapp.com/rspec/rspec-mocks/docs/working-with-legacy-code/message-chains
但是,如果无法做到这一点,您可以删除receive_message_chain
并自行设置链。
line_items_stub = double
# or line_items_stub = Order.new.line_items
# or line_items_stub = [LineItem.new, LineItem.new]
# or line_items_stub = the object that you want
allow_any_instance_of(Order).
to receive(:line_items).
and_return(line_items_stub)
allow(line_items_stub).to receive(:find)
如果您能够删除allow_any_instance_of
,则可以使用and_call_original
在该具体实例上调用line_items的实际实现,即可将message_chain存在。