Reputation: 143
I expect my hash to look like one of these two:
{metadata: {SOME_UNKNOWN_KEY: {transaction_id: 123456}}}
{metadata: {transaction_id: 123456}}
If I'm looking for the key :transaction_id
, I understand that I can use hash_including
to expect a nested key that should be in a particular place, but I'd like to be able to do something like this to cover both options:
expect(something).
to receive(some_method).
with(hash_including(metadata: hash_including_anywhere(:transaction_id)))
Is this possible?
Upvotes: 2
Views: 1677
Reputation: 6649
Sure it's possible!
Looking at how hash_including
is implemented one can see that it's a simple matcher class there:
https://github.com/rspec/rspec-mocks/blob/master/lib/rspec/mocks/argument_matchers.rb#L70
HashIncluding
matcher is based on BaseHashMatcher
and it looks like if you played with some recursive approach to check if there's the key hiding somewhere deeper you should be good to go:
https://github.com/rspec/rspec-mocks/blob/master/lib/rspec/mocks/argument_matchers.rb#L183
You can start from reading the specs for hash_including
to get yourself started: https://github.com/rspec/rspec-mocks/blob/master/spec/rspec/mocks/hash_including_matcher_spec.rb
Defining your own matcher sounds scary because they work like magic in our tests, but they are actually not that complicated to write.
Upvotes: 1