Ruby on rails RSpec:接收\消息\链的匹配参数

Ruby on rails RSpec:接收\消息\链的匹配参数,ruby-on-rails,rspec,Ruby On Rails,Rspec,我正在尝试存根: Thing.where(uuid: options['uuid']).first 通过: 但这又回来了: #<Double (anonymous)> received :first with unexpected arguments expected: ({:uuid=>123}) got: (no args) #收到:第一个带有意外参数 应为:({:uuid=>123}) got:(没有args) 是否有

我正在尝试存根:

Thing.where(uuid: options['uuid']).first
通过:

但这又回来了:

 #<Double (anonymous)> received :first with unexpected arguments
         expected: ({:uuid=>123})
              got: (no args)
#收到:第一个带有意外参数
应为:({:uuid=>123})
got:(没有args)

是否有其他方法可以验证消息链的参数?

当参数与最终方法以外的任何方法相关时,您似乎不能将
结合使用。因此,信息:

#<Double (anonymous)> received :first with unexpected arguments
或者省略参数:

 allow(Thing).to receive_message_chain(:where, :first).and_return(nil)
 expect(Thing.where(uuid: 1).first).to eq nil
不建议IMO使用
receive\u message\u chain
。从文档:

你应该考虑任何使用“接收信息”链的代码嗅觉


下面是我们如何解决类似情况的:

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)
近几个月来,纯粹出于偶然,我发现您实际上可以按照消息链的顺序链接“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)

有时很容易出错(我会间歇性地得到一个错误,说“参数的数量错误(0代表1+)”;虽然这似乎只在一个测试中执行多个接收消息链时发生),但您也可以选择将“with”方法链接起来,因此:

expect(User).to receive_message_chain(:where, :order).with(active: true).with('name ASC')

它不是被写成
allow(Thing)来接收消息链(:where)。首先
?更好的方法是
let(:verifying\u double){instance\u double(YourClass)}
,然后
…返回(verifying\u double)
然后
期望(verifying\u double)。到…
,这样不嵌套就更清晰了。这将执行并通过,但实际上它不会使用
参数测试
。(至少从rspec 3.10开始)将
:其中,:order
name ASC
更改为其他内容,您将看到您的测试仍然(误导性地)通过。@davidempy您不正确。以下过程:
expect(NameserverPair)。接收消息链(:order,:first)。使用('domains\u count ASC')。使用('no\u args)
以下过程不:
expect(NameserverPair)。接收消息链(:order,:first)。使用('domains\u count ASC')。使用('bork')
它正确地失败了:
失败/错误:order('domains_count ASC')。first#received:first,预期会有意外参数:(“bork”)get:(无参数)
使用RSpec 3.7,这正是正确的行为
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)
expect(User).to receive_message_chain(:where, :order).with(active: true).with('name ASC')