Skip to content

Commit

Permalink
Merge pull request #920 from mkasztelnik/171-global-stubs-order
Browse files Browse the repository at this point in the history
Option to invoke local stub before global stub
  • Loading branch information
bblimke authored Nov 12, 2020
2 parents d5d8e65 + 90eaa4a commit bacb8a5
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 8 deletions.
17 changes: 11 additions & 6 deletions lib/webmock/stub_registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@ def initialize
end

def global_stubs
@global_stubs ||= []
@global_stubs ||= Hash.new { |h, k| h[k] = [] }
end

def reset!
self.request_stubs = []
end

def register_global_stub(&block)
def register_global_stub(order = :before_local_stubs, &block)
unless %i[before_local_stubs after_local_stubs].include?(order)
raise ArgumentError.new("Wrong order. Use :before_local_stubs or :after_local_stubs")
end

# This hash contains the responses returned by the block,
# keyed by the exact request (using the object_id).
# That way, there's no race condition in case #to_return
Expand All @@ -38,7 +42,7 @@ def register_global_stub(&block)
response_lock.synchronize { responses.delete(request.object_id) }
})

global_stubs.push stub
global_stubs[order].push stub
end

def register_request_stub(stub)
Expand All @@ -64,9 +68,10 @@ def response_for_request(request_signature)
private

def request_stub_for(request_signature)
(global_stubs + request_stubs).detect { |registered_request_stub|
registered_request_stub.request_pattern.matches?(request_signature)
}
(global_stubs[:before_local_stubs] + request_stubs + global_stubs[:after_local_stubs])
.detect { |registered_request_stub|
registered_request_stub.request_pattern.matches?(request_signature)
}
end

def evaluate_response_for_request(response, request_signature)
Expand Down
4 changes: 2 additions & 2 deletions lib/webmock/webmock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ def self.print_executed_requests
puts WebMock::RequestExecutionVerifier.executed_requests_message
end

def self.globally_stub_request(&block)
WebMock::StubRegistry.instance.register_global_stub(&block)
def self.globally_stub_request(order = :before_local_stubs, &block)
WebMock::StubRegistry.instance.register_global_stub(order, &block)
end

%w(
Expand Down
17 changes: 17 additions & 0 deletions spec/acceptance/shared/stubbing_requests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,23 @@ def stub_non_globally
end
end
end

context "when global stub should be invoked last" do
before do
WebMock.globally_stub_request(:after_local_stubs) do
{ body: "global stub body" }
end
end

it "uses global stub when non-global stub is not defined" do
expect(http_request(:get, "http://www.example.com/").body).to eq("global stub body")
end

it "uses non-global stub first" do
stub_request(:get, "www.example.com").to_return(body: 'non-global stub body')
expect(http_request(:get, "http://www.example.com/").body).to eq("non-global stub body")
end
end
end

describe "when stubbing request with a block evaluated on request" do
Expand Down

0 comments on commit bacb8a5

Please sign in to comment.