`hash_including` matcher breaks `WebMock::Util::Headers.normalize_headers`
came across this while attempting to put an expectation on a mocked request's headers
example test to reproduce:
RSpec.describe "webmock broken normalize_headers test" do
it 'should work' do
WebMock.stub_request(:post, /foo/).to_return(body: proc{|_| {}.to_json })
Faraday.post('http://www.foo.com', {foo: :bar}.to_json, "Content-Type" => 'application/json', "CUSTOM_HEADER" => "value")
expect(WebMock).to have_requested(:post, 'http://www.foo.com').with(
headers: hash_including({
"CUSTOM_HEADER" => "value"
})
)
end
end
This syntax looks like it should work fine judging by the examples in the readme:
But instead, the above example test spits out the following:
Failures:
1) webmock broken normalize_headers test should work
Failure/Error:
expect(WebMock).to have_requested(:post, 'http://www.foo.com').with(
headers: hash_including({
"CUSTOM_HEADER" => "value"
})
)
NoMethodError:
undefined method `map' for #<RSpec::Mocks::ArgumentMatchers::HashIncludingMatcher:0x0000000111c45dd0>
Did you mean? tap
# ./vendor/bundle/ruby/2.6.0/gems/webmock-3.13.0/lib/webmock/util/headers.rb:11:in `normalize_headers'
# ./vendor/bundle/ruby/2.6.0/gems/webmock-3.13.0/lib/webmock/request_pattern.rb:375:in `initialize'
# ./vendor/bundle/ruby/2.6.0/gems/webmock-3.13.0/lib/webmock/request_pattern.rb:60:in `new'
# ./vendor/bundle/ruby/2.6.0/gems/webmock-3.13.0/lib/webmock/request_pattern.rb:60:in `assign_options'
# ./vendor/bundle/ruby/2.6.0/gems/webmock-3.13.0/lib/webmock/request_pattern.rb:28:in `with'
# ./vendor/bundle/ruby/2.6.0/gems/webmock-3.13.0/lib/webmock/rspec/matchers/webmock_matcher.rb:35:in `with'
# ./spec/lib/proxy/rspec_spec.rb:8:in `block (2 levels) in <top (required)>'
# ./vendor/bundle/ruby/2.6.0/gems/webmock-3.13.0/lib/webmock/rspec.rb:37:in `block (2 levels) in <top (required)>'
@cosmicbuffalo hash_including doesn't work for headers, but matching headers behaves like hash_including by default.
"matching headers behaves like hash_including by default" that is not working for me, when I try to match partially the headers, it does not work :(
"matching headers behaves like hash_including by default" that is not working for me, when I try to match partially the headers, it does not work :(
can you please provide an example if it's still relevant?
Not working for me either. To reproduce:
describe "google" do
it "test" do
stub_request(:get, "https://google.com").with(headers: hash_including({})).to_return(body: "")
Faraday.new.get("https://google.com") do |req|
req.headers = { "Not-Included-In-Stub": "true" }
end
expect(WebMock).to have_requested(:get, 'https://google.com')
end
end
Outcome:
I need to be able to do this so that I can partially match headers. Right now is all or nothing.
If I remove the hash_including it simply fails because it doesn't match:
it "test" do
stub_request(:get, "https://google.com").with(headers: {}).to_return(body: "")
Faraday.new.get("https://google.com") do |req|
req.headers = { "Not-Included-In-Stub": "true" }
end
expect(WebMock).to have_requested(:get, 'https://google.com')
end
Outcome:
The reason I'm passing an empty hash {} is because it's the default value of a wrapping function.
@mochetts thank you for reporting. When with(headers: {}) is provided, it doesn't match and it should.
I suggest removing with(headers: {}) completely. from your code as a temporary solution.
What I ended up doing is this: https://github.com/moraki-finance/docuseal/blob/main/spec/spec_helper.rb#L29
Not ideal, but works.