Cached `nil` responses for missing stubs affect subsequent tests
Given the following RSpec test:
require "httpclient"
require "webmock"
require "webmock/rspec/matchers"
RSpec.describe "webmock issue" do
before(:all) do
WebMock.enable!
WebMock.disable_net_connect!
$client = HTTPClient.new(base_url: "https://my.cool.service.com")
end
it "caches nil responses for missing stubs" do
expect {
$client.get('info')
}.to raise_error(WebMock::NetConnectNotAllowedError)
end
it "fails afterwards even if correct stub is present" do
stub = WebMock.stub_request(:get, "https://my.cool.service.com/info")
$client.get('info')
expect(stub).to have_been_requested
end
end
The second example fails iff performed in order. It runs fine when ran alone.
This example is the result of hours of debugging where I finally found that HTTPClientAdapter#webmock_responses caches responses.
Because we have a test where the client is hold by some kind of adapter which is kind of global (simulated by the $client in the example above), this affects follow.-up tests.
We can work around this problem by monkey-patching HTTPClientAdapter#webmock_responses to
def webmock_responses
Hash.new do |hash, request_signature|
synchronize_request_response do
hash[request_signature] = WebMock::StubRegistry.instance.response_for_request(request_signature)
end
end
end
but probably, the memoization is there fore a reason, isn’t it?
@toaster thank you for reporting and for spending time identifying the problem with memoization.
This is the original commit where memoization has been introduced https://github.com/bblimke/webmock/commit/8786b654a32d06891d5c7b0d019db9816c495818
I agree that there should be nothing left in the client instance after the request.
Perhaps that's what is causing the random failures when running WebMock specs https://github.com/bblimke/webmock/issues/711
I will investigate that when I find some time or perhaps someone else will have time to do that.
@toaster this is now fixed in version 3.22.0