rspec / rspec-mocks

RSpec's 'test double' framework, with support for stubbing and mocking
https://rspec.info
MIT License
1.16k stars 357 forks source link

Don't convert keywords to hash in #send for verifying doubles on Ruby 3 #1520

Closed pirj closed 1 year ago

pirj commented 1 year ago

The current re-implementation of send on verifying doubles uses *args by itself. Everything works fine on main for Ruby 2 or lower, but on Ruby 3 this converts keyword arguments to a Hash element inside the args array, which then gets passed to __send__ and then super and (correctly) causes a failure when the method gets a Hash instead of keywords.

Without this patch, the new test passes on Ruby 2.7.6 and fails on Ruby 3.1.2:

Failures:

  1) Expected argument verification (when `#with` is called) when doubling a loaded class for a method with keyword args when using `send` matches against keyword arguments
     Failure/Error: dbl.send(:m, :k => 1)

       #<InstanceDouble(#<Class:0x00007fbd16cf1ba8>) (anonymous)> received :m with unexpected arguments
         expected: ({:k=>1}) (keyword arguments)
              got: ({:k=>1}) (options hash)
       Diff:

With this patch, all tests pass on all Ruby versions.

Fixes #1485

Laykou commented 1 year ago

Do you think this could be released as new version?

Currently I had to load from source:

gem 'rspec-rails', '6.1.0.pre', github: 'rspec/rspec-rails', branch: 'main'
gem 'rspec', '3.13.0.pre', github: 'rspec/rspec', branch: 'main'
gem 'rspec-core', '3.13.0.pre', github: 'rspec/rspec-core', branch: 'main'
gem 'rspec-mocks', github: 'rspec/rspec-mocks', branch: 'main'
gem 'rspec-expectations', github: 'rspec/rspec-expectations', branch: 'main'
gem 'rspec-support', github: 'rspec/rspec-support', branch: 'main'

to fix the issue with mocking of method with keyword arguments

JonRowe commented 1 year ago

Released as 3.12.3

Laykou commented 1 year ago

Thank you! This resolved the "keyword" argument mock issue in Ruby 3.2 for me. Yay! 🥳