【问题标题】:RSpec stub throws wrong number of arguments errorRSpec 存根抛出错误数量的参数错误
【发布时间】:2015-10-28 18:37:24
【问题描述】:

我正在尝试使用新语法对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 错误?

【问题讨论】:

  • 您是否尝试过对Slack 类的任何实例存根,即allow_any_instance_of(Slack).to receive(:channels_join).and_return(true)
  • 原来allow_any_instance_of(Slack::Client)expect_any_instance_of(Slack::Client 解决了这个问题。如果您想将其发布为答案,我会接受它
  • 很高兴它工作了.. :)
  • 我建议你不要使用allow_any_instance_of。它有很多问题。我们建议不要使用它:relishapp.com/rspec/rspec-mocks/v/3-3/docs/… 相反,请参阅下面我建议的修复。

标签: ruby-on-rails ruby rspec mocking


【解决方案1】:

如果您启用了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 传递了第二个参数,期望 respond_to? 将接受两个参数,因为它应该的。

要修复它,您可以(暂时)猴子修补 slack gem:

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

不过,这确实应该在 slack gem 中得到修复,所以我鼓励你与维护者一起打开一个 PR 来修复这个问题。

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

【讨论】:

  • 感谢您指出这一点!公关打开,很高兴了解-b
  • 我在 jruby 1.9 应用程序中升级 RSpec 并遇到了这个问题。我怀疑在 JRuby 的某个地方有一个类似的错误。这个解释让我清楚地知道要寻找什么。现在我只需要寻找它。
猜你喜欢
  • 2023-03-03
  • 1970-01-01
  • 2013-06-22
  • 2018-09-22
  • 1970-01-01
  • 1970-01-01
  • 2017-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多