bblimke / webmock

Library for stubbing and setting expectations on HTTP requests in Ruby.
MIT License
3.98k stars 555 forks source link

Cached `nil` responses for missing stubs affect subsequent tests #1019

Open toaster opened 1 year ago

toaster commented 1 year ago

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?

bblimke commented 1 year ago

@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.

bblimke commented 9 months ago

@toaster this is now fixed in version 3.22.0