RSpec存根抛出错误数量的参数错误

时间:2015-10-28 18:37:25

标签: ruby-on-rails ruby rspec mocking

我尝试使用新语法来存根Slack gem(旧语法会抛出相同的错误):

before :each do
    allow(Slack).to receive(:channels_join).and_return(true)
end

此行抛出wrong number of arguments (2 for 1)。将这条线分成几块,似乎对.to的调用正在抛出错误:

a = allow(Slack)
b = receive(:channels_join)
c = b.and_return(true)
a.to(c)

将参数更改为.to并没有改变任何内容:

a.to(c, c)

会抛出相同的2 for 1错误。

a.to(5)

抛出一个合理的错误:only the receive or receive_messages matchers are supported with allow(...).to, but you have provided: 5

为什么会抛出2 for 1错误?

1 个答案:

答案 0 :(得分:5)

如果您启用了verify_partial_doubles选项,则RSpec会在您存根时检查Slack是否响应:channels_join。很遗憾,Slack.respond_to?implemented incorrectly

def self.respond_to?(method)
  return client.respond_to?(method) || super
end

问题在于Object#respond_to? accepts two arguments(并且多年来,至少1.8.7,如果不是更快!),RSpec传递第二个arg,期待respond_to?因为它应该接受两个参数。

要修复它,你可以(暂时)修补松弛的宝石:

module Slack
  def self.respond_to?(method, include_all=false)
    return client.respond_to?(method, include_all) || super
  end
end

这应该在松弛的宝石中得到解决,所以我鼓励你和修复者一起打开PR。

更广泛地说,当您遇到此类错误时,您可以通过rspec -b(或--backtrace)标记来了解有关该问题的更多信息,该标记将打印完整回溯。在您的情况下,我希望它能够显示RSpec中的respond_to?调用站点以及Slack定义respond_to?仅接受一个参数的行。然后你可以看看那些线来弄清楚发生了什么。