webmock
webmock copied to clipboard
Is there a way to do hash_excluding matching?
Like so:
require 'webmock'
include WebMock::API
stub_request(:post, 'http://example.com/path')
.with(body: hash_excluding({a: '1'}))
.to_return(body: 'b1')
puts Net::HTTP.post_form(URI('http://example.com/path'), {b: '2'}).body
rspec
has this matcher, but it doesn't seem to work for webmock
.
For now there's this workaround for ruby 2.0+
:
module BodyPatternExtensions
def matches?(body, content_type = "")
if @pattern.instance_of?(RSpec::Mocks::ArgumentMatchers::HashExcludingMatcher)
@pattern === body_as_hash(body, content_type)
else
super
end
end
end
module WebMock
class BodyPattern
prepend BodyPatternExtensions
end
end
@x-yuri There is no way to do it, unless you use custom matching block.
Nice workaround though.
The proper solution would require adding hash_excluding
matcher to WebMock,
to make it independent from RSpec.
Perhaps it's worth adding a change to WebMock and allow it to accept any kind of RSpec::Mocks::ArgumentMatchers::* matcher.
There is no way to do it, unless you use custom matching block.
By custom matching block you must be meaning this:
stub_request(:post, 'http://example.com/path')
.with { |request| hash_excluding(a: '1') === Rack::Utils.parse_nested_query(request.body) }
Which brings the question, if I can call with
several times to not end up with only custom matching.
Perhaps it's worth adding a change to WebMock and allow it to accept any kind of RSpec::Mocks::ArgumentMatchers::* matcher.
But there are not only hash matchers there. How will you know what to pass to any one of them?
:+1:
This is a pain for places where you want to ensure that a given header is not present, since webmock will match any superset of the expected values. (i.e. trying to do the opposite case from #276)
Ran into this issue today - guessing it's still awaiting a PR, as it hit me too, returning a
undefined method map for #<RSpec::Mocks::ArgumentMatchers::HashExcludingMatcher
(mostly leaving this comment to add to the google-ability of this line to get to this issue)
Will try the workaround for now... and sadly it doesn't seem to work - the above issue still gets triggered. Guess the monkey patch above is a few years old now :)
In a similar situation where I'm trying to ensure the abscence of a certain header, rather than its presence - not seeing a nice way to go about it.
I was facing a similar issue
Browsing the code I found it was not working because when the registered stubs are being tested for a match HashExcludingMatcher
(that is created by hash_excluding
) is not handling the request body as a Hash, which is the behavior for HashIncludingMatcher
(that works)
I opened this Pull Request as a suggestion to fix this issue: https://github.com/bblimke/webmock/blob/833291d4ce2d5927a738f929db26b594bf4fa7f5/lib/webmock/request_pattern.rb#L286