rspec / rspec-mocks

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

When using keyword arguments in mock expectations and calling with a hash the diff is confusing #1438

Open JonRowe opened 3 years ago

JonRowe commented 3 years ago

When you call keyword argument methods with hashes (e.g. if a method_missing doesn't have a proper ruby2_keywords call or a keyword splat) then the diff is confusing because it looks identical. This is going to be tricky to solve because to the differ, they are both hashes...

Steps to reproduce

class SomeClass
  def method_name(value:)
  end
end

RSpec.describe "SomeClass" do
  it "receives keyword arguments" do
    klass = SomeClass.new
    expect(klass).to receive(:method_name).with(value: [1,2,3])
    klass.method_name({value: [1, 2, 3]})
  end
end

Possible/suggested behaviour

 #<SomeClass (class)> received :method_name with unexpected arguments
         expected: (value: [1, 2, 3])
              got: ({:value =>[1, 2, 3]})

Actual behaviour

 #<SomeClass (class)> received :method_name with unexpected arguments
         expected: ({:value => [1, 2, 3]})
              got: ({:value => [1, 2, 3]})
lukepearcewp commented 2 years ago

I had a similar one to this today:

class Foo
  def bar(opts = {})
  end
end

expect(foo).to receive(:bar).with(baz: "should-have-used-a-hash")

#<Double "Foo"> received :bar with unexpected arguments
     expected: ({:baz=>"should-have-used-a-hash"})
          got: ({:baz=>"should-have-used-a-hash"})
     Diff:

Completely my mistake and it's correct but makes you think rspec is doing something funky at first glance. Would've been nice if the error could perhaps show *args vs **kwargs as the diff or something to help point you in the right direction.