Skip to content

Commit

Permalink
Ensure stub.with block is only called once per request.
Browse files Browse the repository at this point in the history
Previously it was called 2 or even 3 times for one request,
which made it difficult to put any behavior in the hook
besides returning true or false as you had to keep track of the request
to see if the hook was being called again for the same request.
  • Loading branch information
myronmarston committed Nov 18, 2011
1 parent 99f0a75 commit 8786b65
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 23 deletions.
3 changes: 1 addition & 2 deletions lib/webmock/http_lib_adapters/curb_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ def curb_or_webmock
request_signature = build_request_signature
WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)

if WebMock::StubRegistry.instance.registered_request?(request_signature)
webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
if webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
build_curb_response(webmock_response)
WebMock::CallbackRegistry.invoke_callbacks(
{:lib => :curb}, request_signature, webmock_response)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ def send_request_with_webmock(&block)

WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)

if WebMock::StubRegistry.instance.registered_request?(request_signature)
webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
if webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
WebMock::CallbackRegistry.invoke_callbacks(
{:lib => :em_http_request}, request_signature, webmock_response)
client = WebMockHttpClient.new(nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class WebMockHttpConnection < HttpConnection
def webmock_activate_connection(client)
request_signature = client.request_signature

if WebMock::StubRegistry.instance.registered_request?(request_signature)
if client.stubbed_webmock_response
conn = HttpStubConnection.new rand(10000)
post_init

Expand Down Expand Up @@ -95,13 +95,12 @@ def setup(response, uri, error = nil)
def send_request_with_webmock(head, body)
WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)

if WebMock::StubRegistry.instance.registered_request?(request_signature)
webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
on_error("WebMock timeout error") if webmock_response.should_timeout
WebMock::CallbackRegistry.invoke_callbacks({:lib => :em_http_request}, request_signature, webmock_response)
if stubbed_webmock_response
on_error("WebMock timeout error") if stubbed_webmock_response.should_timeout
WebMock::CallbackRegistry.invoke_callbacks({:lib => :em_http_request}, request_signature, stubbed_webmock_response)
EM.next_tick {
setup(make_raw_response(webmock_response), @uri,
webmock_response.should_timeout ? "WebMock timeout error" : nil)
setup(make_raw_response(stubbed_webmock_response), @uri,
stubbed_webmock_response.should_timeout ? "WebMock timeout error" : nil)
}
self
elsif WebMock.net_connect_allowed?(request_signature.uri)
Expand All @@ -128,6 +127,14 @@ def request_signature
@request_signature ||= build_request_signature
end

def stubbed_webmock_response
unless defined?(@stubbed_webmock_response)
@stubbed_webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
end

@stubbed_webmock_response
end

private

def build_webmock_response
Expand Down
13 changes: 9 additions & 4 deletions lib/webmock/http_lib_adapters/httpclient_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ def do_get_with_webmock(req, proxy, conn, stream = false, &block)

WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)

if WebMock::StubRegistry.instance.registered_request?(request_signature)
webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
if webmock_responses[request_signature]
webmock_response = webmock_responses.delete(request_signature)
response = build_httpclient_response(webmock_response, stream, &block)
@request_filter.each do |filter|
filter.filter_response(req, response)
Expand Down Expand Up @@ -76,8 +76,7 @@ def do_request_async_with_webmock(method, uri, query, body, extheader)
req = create_request(method, uri, query, body, extheader)
request_signature = build_request_signature(req)

if WebMock::StubRegistry.instance.registered_request?(request_signature) ||
WebMock.net_connect_allowed?(request_signature.uri)
if webmock_responses[request_signature] || WebMock.net_connect_allowed?(request_signature.uri)
do_request_async_without_webmock(method, uri, query, body, extheader)
else
raise WebMock::NetConnectNotAllowedError.new(request_signature)
Expand Down Expand Up @@ -158,4 +157,10 @@ def build_request_signature(req)
)
end

def webmock_responses
@webmock_responses ||= Hash.new do |hash, request_signature|
hash[request_signature] = WebMock::StubRegistry.instance.response_for_request(request_signature)
end
end

end
3 changes: 1 addition & 2 deletions lib/webmock/http_lib_adapters/net_http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,8 @@ def request_with_webmock(request, body = nil, &block)

WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)

if WebMock::StubRegistry.instance.registered_request?(request_signature)
if webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
@socket = Net::HTTP.socket_type.new
webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
WebMock::CallbackRegistry.invoke_callbacks(
{:lib => :net_http}, request_signature, webmock_response)
build_net_http_response(webmock_response, &block)
Expand Down
4 changes: 1 addition & 3 deletions lib/webmock/http_lib_adapters/patron_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ def handle_request_with_webmock(req)

WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)

if WebMock::StubRegistry.instance.registered_request?(request_signature)
webmock_response =
WebMock::StubRegistry.instance.response_for_request(request_signature)
if webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
WebMock::HttpLibAdapters::PatronAdapter.
handle_file_name(req, webmock_response)
res = WebMock::HttpLibAdapters::PatronAdapter.
Expand Down
4 changes: 1 addition & 3 deletions lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,7 @@ def queue_with_webmock(request)

::WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)

if ::WebMock::StubRegistry.instance.registered_request?(request_signature)
webmock_response =
::WebMock::StubRegistry.instance.response_for_request(request_signature)
if webmock_response = ::WebMock::StubRegistry.instance.response_for_request(request_signature)
::WebMock::HttpLibAdapters::TyphoeusAdapter.
stub_typhoeus(request_signature, webmock_response, self)
webmock_response.raise_error_if_any
Expand Down
7 changes: 7 additions & 0 deletions spec/acceptance/shared/stubbing_requests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,13 @@
http_request(:post, "http://www.example.com/", :body => "jander")
}.should raise_error(WebMock::NetConnectNotAllowedError, %r(Real HTTP connections are disabled. Unregistered request: POST http://www.example.com/ with body 'jander'))
end

it "should call the block only once per request" do
call_count = 0
stub_request(:get, "www.example.com").with { |request| call_count += 1; true }
http_request(:get, "http://www.example.com/").status.should == "200"
call_count.should == 1
end
end
end
end

0 comments on commit 8786b65

Please sign in to comment.