I'm trying to stub:
Thing.where(uuid: options['uuid']).first
Via:
allow(Thing).to receive_message_chain(:where, :first)
.with(uuid: thing_double.uuid)
.and_return(nil)
But this is returning:
#<Double (anonymous)> received :first with unexpected arguments
expected: ({:uuid=>123})
got: (no args)
Is there a different way I should be validating arguments for message chains?
It's sometimes error prone (I'll intermittently get an error saying "wrong number of arguments (0 for 1+)"; although this seems to only happen when performing multiple receive_message_chains in a single test), but you can also opt for chaining your "with" methods thus:
expect(User).to receive_message_chain(:where, :order).with(active: true).with('name ASC')
It doesn't appear that you can use with
in combination with receive_message_chain
when the arguments pertain anything other than the final method. Thus the message:
#<Double (anonymous)> received :first with unexpected arguments
This makes sense -- how can RSpec know which method in the chain should receive the arguments?
To verify the argument expectation, don't stub the chain, just stub where
allow(Thing).to receive(:where).with(uuid: 1).and_return([])
expect(Thing.where(uuid: 1).first).to eq nil
Or omit the arguments:
allow(Thing).to receive_message_chain(:where, :first).and_return(nil)
expect(Thing.where(uuid: 1).first).to eq nil
receive_message_chain
is not recommended IMO. From the docs:
you should consider any use of receive_message_chain a code smell
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With