FeifanZ
FeifanZ

Reputation: 16316

RSpec stub throws wrong number of arguments error

I'm try to stub the Slack gem with the new syntax (old syntax throws the same error):

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

This line throws wrong number of arguments (2 for 1). Breaking up the line into pieces, it seems like the call to .to is throwing the error:

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

Changing the arguments to .to didn't change anything:

a.to(c, c)

throws the same 2 for 1 error.

a.to(5)

throws a reasonable error: only the receive or receive_messages matchers are supported with allow(...).to, but you have provided: 5

Why is the 2 for 1 error being thrown?

Upvotes: 0

Views: 1295

Answers (1)

Myron Marston
Myron Marston

Reputation: 21800

If you have enabled the verify_partial_doubles option than RSpec will check if Slack responds to :channels_join when you stub it. Unfortunately, Slack.respond_to? is implemented incorrectly:

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

The problem is that Object#respond_to? accepts two arguments (and has for years, since at least 1.8.7, if not sooner!), and RSpec passes a 2nd arg, expecting that respond_to? will accept two arguments since it is supposed to.

To fix it, you can (temporarily) monkey patch the slack gem:

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

This should really be fixed in the slack gem, though, so I'd encourage you to open a PR with the maintainers with this fix.

More broadly, when you run into this kind of error, you can learn more about the problem by passing rspec the -b (or --backtrace) flag, which will print the full backtrace. In your situation I would have expected it to show both the respond_to? call site within RSpec and the line where Slack defines respond_to? accepting only one argument. Then you could look at those lines to figure out what's going on.

Upvotes: 6

Related Questions