stub_requests 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.reek.yml +5 -9
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +23 -0
- data/README.md +9 -9
- data/Rakefile +7 -5
- data/lib/stub_requests.rb +30 -16
- data/lib/stub_requests/api.rb +45 -26
- data/lib/stub_requests/callback.rb +3 -1
- data/lib/stub_requests/callback_registry.rb +9 -55
- data/lib/stub_requests/concerns/argument_validation.rb +47 -0
- data/lib/stub_requests/concerns/property.rb +114 -0
- data/lib/stub_requests/concerns/property/validator.rb +137 -0
- data/lib/stub_requests/concerns/register_verb.rb +110 -0
- data/lib/stub_requests/configuration.rb +19 -2
- data/lib/stub_requests/dsl.rb +5 -6
- data/lib/stub_requests/dsl/method_definition.rb +2 -8
- data/lib/stub_requests/endpoint.rb +22 -23
- data/lib/stub_requests/endpoint_registry.rb +157 -0
- data/lib/stub_requests/exceptions.rb +28 -10
- data/lib/stub_requests/request_stub.rb +29 -14
- data/lib/stub_requests/service.rb +55 -7
- data/lib/stub_requests/service_registry.rb +30 -79
- data/lib/stub_requests/stub_registry.rb +22 -80
- data/lib/stub_requests/stub_requests.rb +8 -5
- data/lib/stub_requests/uri.rb +0 -17
- data/lib/stub_requests/utils/fuzzy.rb +70 -0
- data/lib/stub_requests/version.rb +1 -1
- data/lib/stub_requests/webmock/builder.rb +9 -51
- data/lib/stub_requests/webmock/stub_registry_extension.rb +1 -1
- data/lib/tasks/changelog.rake +1 -7
- data/stub_requests.gemspec +1 -0
- data/update_docs.sh +2 -2
- metadata +27 -8
- data/lib/stub_requests/argument_validation.rb +0 -48
- data/lib/stub_requests/endpoint_stub.rb +0 -89
- data/lib/stub_requests/endpoints.rb +0 -246
- data/lib/stub_requests/hash_util.rb +0 -32
- data/lib/stub_requests/observable.rb +0 -18
- data/lib/stub_requests/property.rb +0 -112
- data/lib/stub_requests/property/validator.rb +0 -135
@@ -13,79 +13,42 @@ module StubRequests
|
|
13
13
|
# @author Mikael Henriksson <mikael@zoolutions.se>
|
14
14
|
#
|
15
15
|
class ServiceRegistry
|
16
|
+
# extend "Forwardable"
|
17
|
+
# @!parse extend Forwardable
|
18
|
+
extend Forwardable
|
19
|
+
|
20
|
+
# includes "Singleton"
|
21
|
+
# @!parse include Singleton
|
16
22
|
include Singleton
|
23
|
+
# includes "Enumerable"
|
24
|
+
# @!parse include Enumerable
|
17
25
|
include Enumerable
|
18
26
|
|
19
|
-
|
20
|
-
|
27
|
+
delegate [:each, :[], :[]=, :keys, :delete] => :services
|
28
|
+
|
21
29
|
#
|
22
|
-
#
|
23
|
-
#
|
30
|
+
# @!attribute [rw] services
|
31
|
+
# @return [Concurrent::Map<Symbol, Service>] a map with services
|
32
|
+
attr_reader :services
|
33
|
+
|
24
34
|
#
|
25
|
-
#
|
26
|
-
# register_service(:documents, "https://company.com/api/v1") do
|
27
|
-
# get "documents/:id", as: :show
|
28
|
-
# get "documents", as: :index
|
29
|
-
# post "documents", as: :create
|
30
|
-
# patch "documents/:id", as: :update
|
31
|
-
# delete "documents/:id", as: :destroy
|
32
|
-
# end
|
35
|
+
# Initialize a new instance (used by Singleton)
|
33
36
|
#
|
34
|
-
# @return [Service] a new service or a previously registered service
|
35
37
|
#
|
36
|
-
def
|
37
|
-
|
38
|
-
Docile.dsl_eval(service.endpoints, &block) if block.present?
|
39
|
-
service
|
38
|
+
def initialize
|
39
|
+
@services = Concurrent::Map.new
|
40
40
|
end
|
41
41
|
|
42
42
|
#
|
43
|
-
#
|
43
|
+
# Returns the size of the registry
|
44
44
|
#
|
45
45
|
#
|
46
|
-
# @
|
47
|
-
# @param [Symbol] endpoint_id the id of a registered endpoint
|
48
|
-
# @param [Hash<Symbol>] route_params a map with route parameters
|
46
|
+
# @return [Integer]
|
49
47
|
#
|
50
|
-
|
51
|
-
|
52
|
-
# @example Stub a request to a registered service endpoint
|
53
|
-
# stub_endpoint(:google_api, :get_map_location)
|
54
|
-
# .to_return(body: "No content", status: 204)
|
55
|
-
#
|
56
|
-
# @example Stub a request to a registered service endpoint using block
|
57
|
-
# stub_endpoint(:documents, :index) do
|
58
|
-
# with(headers: { "Accept" => "application/json" }}})
|
59
|
-
# to_return(body: "No content", status: 204)
|
60
|
-
# end
|
61
|
-
#
|
62
|
-
# @return [WebMock::RequestStub] a mocked request
|
63
|
-
#
|
64
|
-
def self.stub_endpoint(service_id, endpoint_id, route_params = {}, &callback)
|
65
|
-
service, endpoint, uri = StubRequests::URI.for_service_endpoint(service_id, endpoint_id, route_params)
|
66
|
-
webmock_stub = WebMock::Builder.build(endpoint.verb, uri, {}, &callback)
|
67
|
-
|
68
|
-
StubRegistry.record(service, endpoint, webmock_stub)
|
69
|
-
::WebMock::StubRegistry.instance.register_request_stub(webmock_stub)
|
70
|
-
end
|
71
|
-
|
72
|
-
# @api private
|
73
|
-
# Used only for testing purposes
|
74
|
-
def self.__stub_endpoint(service_id, endpoint_id, route_params = {})
|
75
|
-
_service, endpoint, uri = StubRequests::URI.for_service_endpoint(service_id, endpoint_id, route_params)
|
76
|
-
endpoint_stub = WebMock::Builder.build(endpoint.verb, uri)
|
77
|
-
|
78
|
-
::WebMock::StubRegistry.instance.register_request_stub(endpoint_stub)
|
79
|
-
end
|
80
|
-
|
81
|
-
#
|
82
|
-
# @!attribute [rw] services
|
83
|
-
# @return [Concurrent::Map<Symbol, Service>] a map with services
|
84
|
-
attr_reader :services
|
85
|
-
|
86
|
-
def initialize
|
87
|
-
@services = Concurrent::Map.new
|
48
|
+
def size
|
49
|
+
keys.size
|
88
50
|
end
|
51
|
+
alias count size
|
89
52
|
|
90
53
|
#
|
91
54
|
# Resets the map with registered services
|
@@ -96,18 +59,6 @@ module StubRequests
|
|
96
59
|
services.clear
|
97
60
|
end
|
98
61
|
|
99
|
-
#
|
100
|
-
# Required by Enumerable
|
101
|
-
#
|
102
|
-
#
|
103
|
-
# @return [Concurrent::Map<Symbol, Service>] an map with services
|
104
|
-
#
|
105
|
-
# @yield used by Enumerable
|
106
|
-
#
|
107
|
-
def each(&block)
|
108
|
-
services.each(&block)
|
109
|
-
end
|
110
|
-
|
111
62
|
#
|
112
63
|
# Registers a service in the registry
|
113
64
|
#
|
@@ -118,11 +69,11 @@ module StubRequests
|
|
118
69
|
# @return [Service] the service that was just registered
|
119
70
|
#
|
120
71
|
def register(service_id, service_uri)
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
72
|
+
service = Service.new(service_id, service_uri)
|
73
|
+
StubRequests.logger.warn("Service already registered #{service}") if self[service_id]
|
74
|
+
|
75
|
+
self[service_id] = service
|
76
|
+
service
|
126
77
|
end
|
127
78
|
|
128
79
|
#
|
@@ -134,7 +85,7 @@ module StubRequests
|
|
134
85
|
# @raise [ServiceNotFound] when the service was not removed
|
135
86
|
#
|
136
87
|
def remove(service_id)
|
137
|
-
|
88
|
+
delete(service_id) || raise(ServiceNotFound, service_id)
|
138
89
|
end
|
139
90
|
|
140
91
|
#
|
@@ -146,7 +97,7 @@ module StubRequests
|
|
146
97
|
# @return [Service] the found service
|
147
98
|
#
|
148
99
|
def find(service_id)
|
149
|
-
|
100
|
+
self[service_id]
|
150
101
|
end
|
151
102
|
|
152
103
|
#
|
@@ -160,7 +111,7 @@ module StubRequests
|
|
160
111
|
# @return [Service]
|
161
112
|
#
|
162
113
|
def find!(service_id)
|
163
|
-
|
114
|
+
self[service_id] || raise(ServiceNotFound, service_id)
|
164
115
|
end
|
165
116
|
end
|
166
117
|
end
|
@@ -15,6 +15,10 @@ module StubRequests
|
|
15
15
|
# @since 0.1.2
|
16
16
|
#
|
17
17
|
class StubRegistry
|
18
|
+
# extend "Forwardable"
|
19
|
+
# @!parse extend Forwardable
|
20
|
+
extend Forwardable
|
21
|
+
|
18
22
|
# includes "Singleton"
|
19
23
|
# @!parse include Singleton
|
20
24
|
include Singleton
|
@@ -22,50 +26,19 @@ module StubRequests
|
|
22
26
|
# @!parse include Enumerable
|
23
27
|
include Enumerable
|
24
28
|
|
25
|
-
|
26
|
-
# Records metrics about stubbed endpoints
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# @param [Service] service a Service
|
30
|
-
# @param [Endpoint] endpoint an Endpoint
|
31
|
-
# @param [WebMock::RequestStub] webmock_stub the stubbed webmock request
|
32
|
-
#
|
33
|
-
# @note the class method of record validates that
|
34
|
-
# configuration option :collect_metrics is true.
|
35
|
-
#
|
36
|
-
# @return [EndpointStub] the stub that was recorded
|
37
|
-
#
|
38
|
-
def self.record(service, endpoint, webmock_stub)
|
39
|
-
# Note: The class method v
|
40
|
-
return unless StubRequests.config.record_metrics?
|
41
|
-
|
42
|
-
instance.record(service, endpoint, webmock_stub)
|
43
|
-
end
|
29
|
+
delegate [:each, :concat] => :stubs
|
44
30
|
|
45
31
|
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
|
49
|
-
#
|
50
|
-
# @param [WebMock::RequestStub] webmock_stub the stubbed webmock request
|
51
|
-
#
|
52
|
-
# @return [void]
|
53
|
-
#
|
54
|
-
def self.mark_as_responded(webmock_stub)
|
55
|
-
instance.mark_as_responded(webmock_stub)
|
56
|
-
end
|
57
|
-
|
58
|
-
#
|
59
|
-
# @!attribute [rw] services
|
60
|
-
# @return [Concurrent::Array<Endpoint>] a map with stubbed endpoints
|
61
|
-
attr_reader :endpoints
|
32
|
+
# @!attribute [r] stubs
|
33
|
+
# @return [Concurrent::Array] a collection of {RequestStub}
|
34
|
+
attr_reader :stubs
|
62
35
|
|
63
36
|
#
|
64
37
|
# Initialize a new registry
|
65
38
|
#
|
66
39
|
#
|
67
40
|
def initialize
|
68
|
-
|
41
|
+
reset
|
69
42
|
end
|
70
43
|
|
71
44
|
#
|
@@ -74,37 +47,22 @@ module StubRequests
|
|
74
47
|
#
|
75
48
|
# @api private
|
76
49
|
def reset
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
#
|
81
|
-
# Required by Enumerable
|
82
|
-
#
|
83
|
-
#
|
84
|
-
# @return [Concurrent::Array<Endpoint>] an array with stubbed endpoints
|
85
|
-
#
|
86
|
-
# @yield used by Enumerable
|
87
|
-
#
|
88
|
-
def each(&block)
|
89
|
-
endpoints.each(&block)
|
50
|
+
@stubs = Concurrent::Array.new
|
90
51
|
end
|
91
52
|
|
92
53
|
#
|
93
|
-
# Records
|
54
|
+
# Records a WebMock::RequestStub as stubbed
|
94
55
|
#
|
56
|
+
# @param [WebMock::RequestStub] webmock_stub <description>
|
95
57
|
#
|
96
|
-
# @
|
97
|
-
# @param [Endpoint] endpoint a string with a base_uri to the service
|
98
|
-
# @param [WebMock::RequestStub] webmock_stub the stubbed request
|
58
|
+
# @return [RequestStub]
|
99
59
|
#
|
100
|
-
|
101
|
-
|
102
|
-
def record(service, endpoint, webmock_stub)
|
103
|
-
endpoint_stub = find_or_initialize_endpoint_stub(service, endpoint)
|
104
|
-
endpoint_stub.record(webmock_stub)
|
60
|
+
def record(endpoint_id, webmock_stub)
|
61
|
+
return unless StubRequests.config.record_stubs?
|
105
62
|
|
106
|
-
|
107
|
-
|
63
|
+
request_stub = RequestStub.new(endpoint_id, webmock_stub)
|
64
|
+
concat([request_stub])
|
65
|
+
request_stub
|
108
66
|
end
|
109
67
|
|
110
68
|
#
|
@@ -117,10 +75,10 @@ module StubRequests
|
|
117
75
|
# @return [void]
|
118
76
|
#
|
119
77
|
def mark_as_responded(webmock_stub)
|
120
|
-
return unless (request_stub =
|
78
|
+
return unless (request_stub = find_by_webmock_stub(webmock_stub))
|
121
79
|
|
122
80
|
request_stub.mark_as_responded
|
123
|
-
CallbackRegistry.invoke_callbacks(request_stub)
|
81
|
+
CallbackRegistry.instance.invoke_callbacks(request_stub)
|
124
82
|
request_stub
|
125
83
|
end
|
126
84
|
|
@@ -132,24 +90,8 @@ module StubRequests
|
|
132
90
|
#
|
133
91
|
# @return [RequestStub] the request_stubbed matching the request stub
|
134
92
|
#
|
135
|
-
def
|
136
|
-
|
137
|
-
endpoint.find_by(attribute: :request_stub, value: webmock_stub)
|
138
|
-
end.compact.first
|
139
|
-
end
|
140
|
-
|
141
|
-
private
|
142
|
-
|
143
|
-
def find_or_initialize_endpoint_stub(service, endpoint)
|
144
|
-
find_endpoint_stub(service, endpoint) || initialize_endpoint_stub(service, endpoint)
|
145
|
-
end
|
146
|
-
|
147
|
-
def find_endpoint_stub(service, endpoint)
|
148
|
-
find { |ep| ep.service_id == service.id && ep.endpoint_id == endpoint.id }
|
149
|
-
end
|
150
|
-
|
151
|
-
def initialize_endpoint_stub(service, endpoint)
|
152
|
-
EndpointStub.new(service, endpoint)
|
93
|
+
def find_by_webmock_stub(webmock_stub)
|
94
|
+
find { |stub| stub.webmock_stub == webmock_stub }
|
153
95
|
end
|
154
96
|
end
|
155
97
|
end
|
@@ -22,11 +22,6 @@ module StubRequests
|
|
22
22
|
# @!parse extend API
|
23
23
|
include API
|
24
24
|
|
25
|
-
#
|
26
|
-
# @!attribute [rw] logger
|
27
|
-
# @return [Logger] the logger to use in the gem
|
28
|
-
attr_accessor :logger
|
29
|
-
|
30
25
|
#
|
31
26
|
# Allows the gem to be configured
|
32
27
|
#
|
@@ -50,6 +45,14 @@ module StubRequests
|
|
50
45
|
@config ||= Configuration.new
|
51
46
|
end
|
52
47
|
|
48
|
+
def logger
|
49
|
+
config.logger
|
50
|
+
end
|
51
|
+
|
52
|
+
def logger=(obj)
|
53
|
+
config.logger = obj
|
54
|
+
end
|
55
|
+
|
53
56
|
#
|
54
57
|
# The current version of the gem
|
55
58
|
#
|
data/lib/stub_requests/uri.rb
CHANGED
@@ -40,22 +40,5 @@ module StubRequests
|
|
40
40
|
def self.safe_join(host, path)
|
41
41
|
[host.chomp("/"), path.sub(%r{\A/}, "")].join("/")
|
42
42
|
end
|
43
|
-
|
44
|
-
#
|
45
|
-
# UtilityFunction to construct the full URI for a service endpoint
|
46
|
-
#
|
47
|
-
# @param [Symbol] service_id the id of a service
|
48
|
-
# @param [Symbol] endpoint_id the id of an endpoint
|
49
|
-
# @param [Hash<Symbol>] route_params hash with route_params
|
50
|
-
#
|
51
|
-
# @return [Array<Service, Endpoint, String] the service, endpoint and full URI
|
52
|
-
#
|
53
|
-
def self.for_service_endpoint(service_id, endpoint_id, route_params)
|
54
|
-
service = ServiceRegistry.instance.find!(service_id)
|
55
|
-
endpoint = service.endpoints.find!(endpoint_id)
|
56
|
-
uri = URI::Builder.build(service.uri, endpoint.path, route_params)
|
57
|
-
|
58
|
-
[service, endpoint, uri]
|
59
|
-
end
|
60
43
|
end
|
61
44
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Abstraction over WebMock to reduce duplication
|
5
|
+
#
|
6
|
+
# @author Mikael Henriksson <mikael@zoolutions.se>
|
7
|
+
# @since 0.1.0
|
8
|
+
#
|
9
|
+
module StubRequests
|
10
|
+
#
|
11
|
+
# Module Utils provides a namespace for utility module
|
12
|
+
#
|
13
|
+
# @author Mikael Henriksson <mikael@zoolutions.se>
|
14
|
+
#
|
15
|
+
module Utils
|
16
|
+
#
|
17
|
+
# Provides convenience methods for hashes
|
18
|
+
#
|
19
|
+
# @author Mikael Henriksson <mikael@zoolutions.se>
|
20
|
+
#
|
21
|
+
module Fuzzy
|
22
|
+
#
|
23
|
+
# @return [Regexp] a pattern excluding all except alphanumeric
|
24
|
+
FILTER_REGEX = /(^\w\d)/.freeze
|
25
|
+
#
|
26
|
+
# Find strings that are similar
|
27
|
+
#
|
28
|
+
#
|
29
|
+
# @param [String] original a string to match
|
30
|
+
# @param [Array<String>] others an array of string to search
|
31
|
+
#
|
32
|
+
# @return [Array] Returns
|
33
|
+
#
|
34
|
+
def self.match(original, others)
|
35
|
+
matches = compute_distances(original, others).sort.reverse
|
36
|
+
filter_matches(matches.to_h)
|
37
|
+
end
|
38
|
+
|
39
|
+
# :nodoc:
|
40
|
+
def self.filter_matches(matches)
|
41
|
+
suggestions = matches.values
|
42
|
+
return suggestions if suggestions.size <= 3
|
43
|
+
|
44
|
+
matches.select { |distance, _| distance >= 0.7 }
|
45
|
+
.values
|
46
|
+
end
|
47
|
+
|
48
|
+
# :nodoc:
|
49
|
+
def self.compute_distances(original, others)
|
50
|
+
others.each_with_object([]) do |other, memo|
|
51
|
+
memo << [jaro_distance(original, other), other]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# :nodoc:
|
56
|
+
def self.jaro_distance(original, other)
|
57
|
+
JaroWinkler.jaro_distance(
|
58
|
+
normalize_string(original),
|
59
|
+
normalize_string(other),
|
60
|
+
StubRequests.config.jaro_options,
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
# :nodoc:
|
65
|
+
def self.normalize_string(value)
|
66
|
+
value.to_s.gsub(FILTER_REGEX, "")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -21,32 +21,25 @@ module StubRequests
|
|
21
21
|
# @since 0.1.2
|
22
22
|
#
|
23
23
|
class Builder
|
24
|
-
include HashUtil
|
25
|
-
|
26
24
|
#
|
27
25
|
# Builds and registers a WebMock::RequestStub
|
28
26
|
#
|
29
27
|
#
|
30
28
|
# @param [Symbol] verb a HTTP verb/method
|
31
29
|
# @param [String] uri a URI to call
|
32
|
-
# @param [Hash<Symbol>] options request/response options for Webmock::RequestStub
|
33
30
|
#
|
34
31
|
# @yield a callback to eventually yield to the caller
|
35
32
|
#
|
36
|
-
# @return [WebMock::RequestStub]
|
33
|
+
# @return [WebMock::RequestStub]
|
37
34
|
#
|
38
|
-
def self.build(verb, uri,
|
39
|
-
new(verb, uri,
|
35
|
+
def self.build(verb, uri, &callback)
|
36
|
+
new(verb, uri, &callback).build
|
40
37
|
end
|
41
38
|
|
42
39
|
#
|
43
|
-
# @!attribute [r]
|
40
|
+
# @!attribute [r] webmock_stub
|
44
41
|
# @return [WebMock::RequestStub] a stubbed webmock request
|
45
|
-
attr_reader :
|
46
|
-
#
|
47
|
-
# @!attribute [r] options
|
48
|
-
# @return [Hash<Symbol>] options for the stub_request
|
49
|
-
attr_reader :options
|
42
|
+
attr_reader :webmock_stub
|
50
43
|
#
|
51
44
|
# @!attribute [r] callback
|
52
45
|
# @return [Block] call back when given a block
|
@@ -58,13 +51,11 @@ module StubRequests
|
|
58
51
|
#
|
59
52
|
# @param [Symbol] verb a HTTP verb/method
|
60
53
|
# @param [String] uri a URI to call
|
61
|
-
# @param [Hash<Symbol>] options request/response options for Webmock::RequestStub
|
62
54
|
#
|
63
55
|
# @yield a block to eventually yield to the caller
|
64
56
|
#
|
65
|
-
def initialize(verb, uri,
|
66
|
-
@
|
67
|
-
@options = options
|
57
|
+
def initialize(verb, uri, &callback)
|
58
|
+
@webmock_stub = ::WebMock::RequestStub.new(verb, uri)
|
68
59
|
@callback = callback
|
69
60
|
end
|
70
61
|
|
@@ -75,41 +66,8 @@ module StubRequests
|
|
75
66
|
# @return [WebMock::RequestStub] the registered stub
|
76
67
|
#
|
77
68
|
def build
|
78
|
-
if callback.present?
|
79
|
-
|
80
|
-
else
|
81
|
-
prepare_mock_request
|
82
|
-
end
|
83
|
-
|
84
|
-
request_stub
|
85
|
-
end
|
86
|
-
|
87
|
-
private
|
88
|
-
|
89
|
-
def prepare_mock_request
|
90
|
-
prepare_with
|
91
|
-
prepare_to_return
|
92
|
-
prepare_to_raise
|
93
|
-
request_stub.to_timeout if options[:timeout]
|
94
|
-
request_stub
|
95
|
-
end
|
96
|
-
|
97
|
-
def prepare_with
|
98
|
-
HashUtil.compact(options[:request]) do |request_options|
|
99
|
-
request_stub.with(request_options)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def prepare_to_return
|
104
|
-
HashUtil.compact(options[:response]) do |response_options|
|
105
|
-
request_stub.to_return(response_options)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def prepare_to_raise
|
110
|
-
return unless (error = options[:error])
|
111
|
-
|
112
|
-
request_stub.to_raise(*Array(error))
|
69
|
+
Docile.dsl_eval(webmock_stub, &callback) if callback.present?
|
70
|
+
webmock_stub
|
113
71
|
end
|
114
72
|
end
|
115
73
|
end
|