dor*_*emi 6 rspec ruby-on-rails
我试图存根:
Thing.where(uuid: options['uuid']).first
Run Code Online (Sandbox Code Playgroud)
通过:
allow(Thing).to receive_message_chain(:where, :first)
.with(uuid: thing_double.uuid)
.and_return(nil)
Run Code Online (Sandbox Code Playgroud)
但这是回归:
#<Double (anonymous)> received :first with unexpected arguments
expected: ({:uuid=>123})
got: (no args)
Run Code Online (Sandbox Code Playgroud)
我应该以不同的方式验证消息链的参数吗?
以下是我们解决类似情况的方法:
expect(Theme).to receive(:scoped).and_return(double('scope').tap do |scope|
expect(scope).to receive(:includes).with(:categories).and_return scope
expect(scope).to receive(:where).with(categories: { parent_id: '1'}).and_return scope
expect(scope).to receive(:order).with('themes.updated_at DESC').and_return scope
expect(scope).to receive(:offset).with(10).and_return scope
expect(scope).to receive(:limit).with(10000)
end)
Run Code Online (Sandbox Code Playgroud)
最近几个月,纯粹是偶然,我发现您实际上可以按照消息链的顺序链接“with”调用。因此,前面的例子就变成了这样:
expect(Theme).to receive_message_chain(:scoped, :includes, :where, :order, :offset, :limit).with(no_args).with(:categories).with(categories: { parent_id: '1'}).with('themes.updated_at DESC').with(10).with(10000)
Run Code Online (Sandbox Code Playgroud)
当参数与最终方法以外的任何内容相关时,您似乎无法with结合使用receive_message_chain.因此消息:
#<Double (anonymous)> received :first with unexpected arguments
Run Code Online (Sandbox Code Playgroud)
这是有道理的 - RSpec如何知道链中的哪个方法应该接收参数?
要验证参数期望,请不要对链进行存根,只需存根 where
allow(Thing).to receive(:where).with(uuid: 1).and_return([])
expect(Thing.where(uuid: 1).first).to eq nil
Run Code Online (Sandbox Code Playgroud)
或者省略参数:
allow(Thing).to receive_message_chain(:where, :first).and_return(nil)
expect(Thing.where(uuid: 1).first).to eq nil
Run Code Online (Sandbox Code Playgroud)
receive_message_chain不推荐IMO.来自文档:
你应该考虑使用receive_message_chain代码气味
| 归档时间: |
|
| 查看次数: |
3597 次 |
| 最近记录: |