To expand further.

If I'd continued using position arguments and changed from:

def parse(body)

to

def parse(body, headers)

the instance double could calls to this were using the correct number of 
arguments.

Alternatively if I was already using keyword arguments and added another 
one:

def parse(body:)

to

def parse(body:, headers: {})

it would also get picked up.

It's only because passing keywords arguments to a method can be interpreted 
as either a single hash or multiple arguments that this isn't picked up.

Steve.

On Tuesday, 19 September 2017 14:33:22 UTC+8, Steven Webb wrote:
>
> Thank you.
>
> I guess I was hoping that when the instance double verified that the 
> message matches the method signature it would determine that I was trying 
> to use keyword arguments instead of a hash.
>
> Steve.
>
> On Tuesday, 19 September 2017 14:20:10 UTC+8, Myron Marston wrote:
>>
>> What goal do you have in mind for this test? From the examples you gave, 
>> it looks like you are only testing how RSpec’s verifying doubles work. For 
>> example, this expectation:
>>
>> expect(html).to respond_to(:parse).with_keywords(:body, :headers)
>>
>> …isn’t exercising your code at all, because you’ve declared html as a 
>> test double, so it’s just testing how doubles work. If you’re trying to 
>> test the HTML class, you should not use a double in its place. Test doubles 
>> are intended for when you want to control the environment in which you test 
>> something, by replacing some collaborators with fake versions. They’re not 
>> intended to ever replace the thing you are testing—once you do that, you’re 
>> no longer testing the thing.
>>
>> Myron
>> ​
>>
>> On Mon, Sep 18, 2017 at 11:03 PM, Steven Webb <[email protected]> 
>> wrote:
>>
>>> I'm having trouble testing a method signature change from taking a 
>>> single argument (a hash) to using keyword arguments. I've created a 
>>> contrived example of HTML parsing to simplify things (I'm not actually 
>>> writing a html parser):
>>>
>>> class HTML
>>>   def parse(body) # body is a hash
>>>     ...
>>>   end
>>> end
>>>
>>> I want to update it so that it can take an optional headers argument. It 
>>> becomes:
>>>
>>> class HTML
>>>   def parse(body: , headers: {}) # body and headers are both hashes
>>>   end
>>> end
>>>
>>> In a related unit test of a different class I'm using something like 
>>> this:
>>>
>>> RSpec.describe "calling the parser" do
>>>   let(:html) { instance_double("HTML", parse: nil) }
>>>   let(:body) { double("body") }
>>>   let(:headers) { double("headers") }
>>>
>>>   before { html.parse(body: body, headers: headers) }
>>>
>>>   it "allows passing optional headers" do
>>>     expect(html).to have_received(:parse).with(body: body, headers: 
>>> headers)
>>>   end
>>> end
>>>
>>> The problem I've got is that this test passes before updating the HTML 
>>> class. After updating the HTML class it correctly detects the keywords as 
>>> arguments and passes. Before it incorrectly determines the keywords are the 
>>> "body" hash and passes. Both are valid ruby, but the method signature has 
>>> changed (at least to me, possibly not to the VM). I tried:
>>>
>>> it "allows an optional headers argument" do
>>>   expect(html).to respond_to(:parse).with_keywords(:body, :headers)
>>> end
>>>
>>> but that fails (presumably the instance double is using method_missing).
>>>
>>>   1) calling the parser allows an optional headers argument
>>>      Failure/Error: expect(html).to 
>>> respond_to(:parse).with_keywords(:body, :headers)
>>>        expected #<InstanceDouble(HTML) (anonymous)> to respond to :parse 
>>> with keywords :body and :headers
>>>      # ./spec/keyword_args_spec.rb:40:in `block (2 levels) in <top 
>>> (required)>'
>>>
>>> Can anyone explain how I should be testing this correctly?
>>>
>>> Thanks
>>>
>>> Steve.
>>>
>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "rspec" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to [email protected].
>>> To post to this group, send email to [email protected].
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/rspec/8dbe9153-45c0-44f7-a0be-e6fa6ceffd7e%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/rspec/8dbe9153-45c0-44f7-a0be-e6fa6ceffd7e%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rspec/e9ba5c1c-bbed-4b71-84d3-078d31fd7a5f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to