rspec-mocks
rspec-mocks copied to clipboard
Using the last argument as keyword parameters is deprecated for arbitrary handling with a block
Subject of the issue
I am performing a complex expectation as described in the arbitrary handling section of the docs. Here is the expectation:
expect(double).to receive(:method) do |item:, &block|
expect(item).to eq(item)
expect(another_double).to receive(:another_method)
# ...other expectations...
block.call(another_double)
end
I get the following warning from Ruby 2.7:
/Users/foo/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/rspec-mocks-3.9.1/lib/rspec/mocks/message_expectation.rb:694: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/Users/foo/project/spec/bar_spec.rb:33: warning: The called method `call' is defined here
where the line mentioned is the first line in the Ruby snippet above.
Your environment
- Ruby version: 2.7.0
- rspec-mocks version: 3.9.1
I am not sure how I can fix this; tried expect(double).to receive(:method) do |item:, **kwargs, &block|
but it yielded the same error.
@linkyndy Would you like to tackle that? You can get some inspiration from recent commits in rspec-expectations
.
PS Not sure if this works as intended:
expect(item).to eq(item)
What are "# ...other expectations..." exactly? Won't it be sufficient to expect(double).to receive(...).with(...).and_call_original
instead if all your expectations are made on arguments? Will you get the same deprecation message when specifying with(item: item)
?
Thanks for your quick answer @pirj! I would love to tackle that, however I can't consider that one of my priorities at the moment, unfortunately.
I've updated my snippet. The other expectations are related to the double that's yielded to the given block. I could stub method
to yield another_double
and have all expectations linear, rather than nested, indeed.
Thanks for pointing out the silly first expectation, also! 😊
can't consider that one of my priorities at the moment, unfortunately.
No rush, we're slowly moving there, no work on rspec-mocks
has been done yet.
expect(another_double).to receive(:another_method)
I believe you can move this out of the block and it will have the same effect:
expect(double).to receive(:method) do |item:, &block|
expect(item).to eq(item_double)
# ...other expectations...
block.call(another_double)
end
expect(another_double).to receive(:another_method)
This will get you closer to with(...)
option.
Yes, I did it that way and removed the block altogether. I thought it was more expressive with the block, but it's not that big of a difference. Thanks!
I think we can keep this issue open, to actually solve the Ruby warning at some point.
I think I am running into this same issue. I'm getting:
/home/josh/.rvm/gems/ruby-2.7.0/gems/rspec-mocks-3.9.1/lib/rspec/mocks/message_expectation.rb:694: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
With a spec like this:
allow(File).to receive(:read) do |*args, **kwargs|
if args.first == "special"
""
else
IO.read(*args, **kwargs)
end
end
(in this test I wanted to handle a certain file in a special way but actually read the other files)
Most likely you are, sorry! We are working on this but its complicated to fix even through its just a warning.