Reputation: 16316
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
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