webmock 1.11.0 → 1.12.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.travis.yml +1 -2
- data/CHANGELOG.md +42 -1
- data/Gemfile +2 -1
- data/README.md +350 -225
- data/Rakefile +0 -12
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +2 -2
- data/lib/webmock/http_lib_adapters/em_http_request/em_http_request_1_x.rb +1 -1
- data/lib/webmock/http_lib_adapters/excon_adapter.rb +2 -2
- data/lib/webmock/http_lib_adapters/net_http.rb +1 -1
- data/lib/webmock/minitest.rb +3 -3
- data/lib/webmock/rack_response.rb +5 -0
- data/lib/webmock/util/query_mapper.rb +4 -3
- data/lib/webmock/version.rb +1 -1
- data/lib/webmock/webmock.rb +14 -12
- data/minitest/test_helper.rb +6 -3
- data/minitest/test_webmock.rb +1 -2
- data/minitest/webmock_spec.rb +3 -3
- data/spec/acceptance/curb/curb_spec.rb +6 -3
- data/spec/acceptance/em_http_request/em_http_request_spec.rb +7 -0
- data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +1 -0
- data/spec/acceptance/net_http/net_http_spec.rb +5 -0
- data/spec/support/webmock_server.rb +5 -1
- data/webmock.gemspec +2 -2
- metadata +25 -26
- data/.rvmrc +0 -1
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,46 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
|
4
|
+
## 1.12.0
|
5
|
+
|
6
|
+
* Not using Gem spec anymore to check loaded Curb version.
|
7
|
+
|
8
|
+
* `WebMock.disable_net_connect!` now accepts array of regexps as allow param:
|
9
|
+
|
10
|
+
i.e. `WebMock.disable_net_connect!(:allow => [/google.com/, /yahoo.com/])`
|
11
|
+
|
12
|
+
Thanks to [Bastien Vaucher](https://github.com/bastien)
|
13
|
+
|
14
|
+
* Fixed `on_header` Curb callback behaviour in Curb adapter
|
15
|
+
|
16
|
+
Thanks to [Joel Chippindale](https://github.com/mocoso)
|
17
|
+
|
18
|
+
* Fixed aws-sdk compatibility with Ruby 2.0, by supporting `continue_timeout` accessor on Net::HTTP socket.
|
19
|
+
|
20
|
+
Thanks to [Lin Jen-Shin](https://github.com/godfat)
|
21
|
+
|
22
|
+
* Fixed WebMock::Server to not give "log writing failed. can't be called from trap context" warning with Ruby 2.0
|
23
|
+
|
24
|
+
Thanks to [Murahashi Sanemat Kenichi](https://github.com/sanemat)
|
25
|
+
|
26
|
+
* Added support for EM-HTTP-Request streaming data off disk feature.
|
27
|
+
|
28
|
+
Thanks to [Lin Jen-Shin](https://github.com/godfat)
|
29
|
+
|
30
|
+
* Added compatibility with Minitest 5
|
31
|
+
|
32
|
+
Thanks to [Tim Kurvers](https://github.com/timkurvers)
|
33
|
+
|
34
|
+
* Excon >= 0.22 compatibility.
|
35
|
+
|
36
|
+
* README has nice sytnax hightlighting and fixed code styling!
|
37
|
+
|
38
|
+
Thanks to [Ilya Vassilevsky](https://github.com/vassilevsky)
|
39
|
+
|
40
|
+
* Compatibility with Rails 4 `rack.session.options`
|
41
|
+
|
42
|
+
Thanks to [gotwalt](https://github.com/gotwalt)
|
43
|
+
|
3
44
|
## 1.11.0
|
4
45
|
|
5
46
|
* Excon >= 0.17 support.
|
@@ -57,7 +98,7 @@
|
|
57
98
|
|
58
99
|
* Fixed issues with registering http requests in multi-threaded environments
|
59
100
|
|
60
|
-
Thanks to [
|
101
|
+
Thanks to [Tom Beauvais](https://github.com/tbeauvais)
|
61
102
|
|
62
103
|
* Bumped Crack version to >=0.3.2
|
63
104
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -29,11 +29,11 @@ Supported HTTP libraries
|
|
29
29
|
Supported Ruby Interpreters
|
30
30
|
---------------------------
|
31
31
|
|
32
|
-
* MRI 1.8.6
|
33
32
|
* MRI 1.8.7
|
34
33
|
* MRI 1.9.1
|
35
34
|
* MRI 1.9.2
|
36
35
|
* MRI 1.9.3
|
36
|
+
* MRI 2.0.0
|
37
37
|
* REE 1.8.7
|
38
38
|
* JRuby
|
39
39
|
* Rubinius
|
@@ -52,32 +52,42 @@ Supported Ruby Interpreters
|
|
52
52
|
|
53
53
|
Add the following code to `test/test_helper.rb`
|
54
54
|
|
55
|
-
|
55
|
+
```ruby
|
56
|
+
require 'webmock/test_unit'
|
57
|
+
```
|
56
58
|
|
57
59
|
### RSpec
|
58
60
|
|
59
61
|
Add the following code to `spec/spec_helper`:
|
60
62
|
|
61
|
-
|
63
|
+
```ruby
|
64
|
+
require 'webmock/rspec'
|
65
|
+
```
|
62
66
|
|
63
67
|
### MiniTest
|
64
68
|
|
65
69
|
Add the following code to `test/test_helper`:
|
66
70
|
|
67
|
-
|
71
|
+
```ruby
|
72
|
+
require 'webmock/minitest'
|
73
|
+
```
|
68
74
|
|
69
75
|
### Cucumber
|
70
76
|
|
71
|
-
|
77
|
+
Create a file `features/support/webmock.rb` with the following contents:
|
72
78
|
|
73
|
-
|
79
|
+
```ruby
|
80
|
+
require 'webmock/cucumber'
|
81
|
+
```
|
74
82
|
|
75
83
|
### Outside a test framework
|
76
84
|
|
77
85
|
You can also use WebMock outside a test framework:
|
78
86
|
|
79
|
-
|
80
|
-
|
87
|
+
```ruby
|
88
|
+
require 'webmock'
|
89
|
+
include WebMock::API
|
90
|
+
```
|
81
91
|
|
82
92
|
## Examples
|
83
93
|
|
@@ -88,268 +98,342 @@ You can also use WebMock outside a test framework:
|
|
88
98
|
|
89
99
|
### Stubbed request based on uri only and with the default response
|
90
100
|
|
91
|
-
|
101
|
+
```ruby
|
102
|
+
stub_request(:any, "www.example.com")
|
92
103
|
|
93
|
-
|
104
|
+
Net::HTTP.get("www.example.com", "/") # ===> Success
|
105
|
+
```
|
94
106
|
|
95
107
|
### Stubbing requests based on method, uri, body and headers
|
96
108
|
|
97
|
-
|
109
|
+
```ruby
|
110
|
+
stub_request(:post, "www.example.com").with(:body => "abc", :headers => { 'Content-Length' => 3 })
|
98
111
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
112
|
+
uri = URI.parse("http://www.example.com/")
|
113
|
+
req = Net::HTTP::Post.new(uri.path)
|
114
|
+
req['Content-Length'] = 3
|
115
|
+
|
116
|
+
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
117
|
+
http.request(req, "abc")
|
118
|
+
end # ===> Success
|
119
|
+
```
|
105
120
|
|
106
121
|
### Matching request body and headers against regular expressions
|
107
122
|
|
108
|
-
|
109
|
-
|
123
|
+
```ruby
|
124
|
+
stub_request(:post, "www.example.com").
|
125
|
+
with(:body => /^.*world$/, :headers => {"Content-Type" => /image\/.+/}).to_return(:body => "abc")
|
126
|
+
|
127
|
+
uri = URI.parse('http://www.example.com/')
|
128
|
+
req = Net::HTTP::Post.new(uri.path)
|
129
|
+
req['Content-Type'] = 'image/png'
|
110
130
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
http.request(req, 'hello world')
|
116
|
-
} # ===> Success
|
131
|
+
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
132
|
+
http.request(req, 'hello world')
|
133
|
+
end # ===> Success
|
134
|
+
```
|
117
135
|
|
118
136
|
### Matching request body against a hash. Body can be URL-Encoded, JSON or XML.
|
119
137
|
|
120
|
-
|
121
|
-
|
138
|
+
```ruby
|
139
|
+
stub_http_request(:post, "www.example.com").
|
140
|
+
with(:body => {:data => {:a => '1', :b => 'five'}})
|
122
141
|
|
123
|
-
|
124
|
-
|
142
|
+
RestClient.post('www.example.com', "data[a]=1&data[b]=five",
|
143
|
+
:content_type => 'application/x-www-form-urlencoded') # ===> Success
|
125
144
|
|
126
|
-
|
127
|
-
|
145
|
+
RestClient.post('www.example.com', '{"data":{"a":"1","b":"five"}}',
|
146
|
+
:content_type => 'application/json') # ===> Success
|
128
147
|
|
129
|
-
|
130
|
-
|
148
|
+
RestClient.post('www.example.com', '<data a="1" b="five" />',
|
149
|
+
:content_type => 'application/xml') # ===> Success
|
150
|
+
```
|
131
151
|
|
132
152
|
### Matching request body against partial hash.
|
133
153
|
|
134
|
-
|
135
|
-
|
154
|
+
```ruby
|
155
|
+
stub_http_request(:post, "www.example.com").
|
156
|
+
with(:body => hash_including({:data => {:a => '1', :b => 'five'}}))
|
136
157
|
|
137
|
-
|
138
|
-
|
158
|
+
RestClient.post('www.example.com', "data[a]=1&data[b]=five&x=1",
|
159
|
+
:content_type => 'application/x-www-form-urlencoded') # ===> Success
|
160
|
+
```
|
139
161
|
|
140
162
|
### Matching custom request headers
|
141
163
|
|
142
|
-
|
164
|
+
```ruby
|
165
|
+
stub_request(:any, "www.example.com").with(:headers=>{ 'Header-Name' => 'Header-Value' })
|
166
|
+
|
167
|
+
uri = URI.parse('http://www.example.com/')
|
168
|
+
req = Net::HTTP::Post.new(uri.path)
|
169
|
+
req['Header-Name'] = 'Header-Value'
|
143
170
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
http.request(req, 'abc')
|
149
|
-
} # ===> Success
|
171
|
+
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
172
|
+
http.request(req, 'abc')
|
173
|
+
end # ===> Success
|
174
|
+
```
|
150
175
|
|
151
176
|
### Matching multiple headers with the same name
|
152
177
|
|
153
|
-
|
178
|
+
```ruby
|
179
|
+
stub_http_request(:get, 'www.example.com').with(:headers => {'Accept' => ['image/jpeg', 'image/png'] })
|
154
180
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
181
|
+
req = Net::HTTP::Get.new("/")
|
182
|
+
req['Accept'] = ['image/png']
|
183
|
+
req.add_field('Accept', 'image/jpeg')
|
184
|
+
Net::HTTP.start("www.example.com") {|http| http.request(req) } # ===> Success
|
185
|
+
```
|
159
186
|
|
160
187
|
### Matching requests against provided block
|
161
188
|
|
162
|
-
|
163
|
-
|
189
|
+
```ruby
|
190
|
+
stub_request(:post, "www.example.com").with { |request| request.body == "abc" }
|
191
|
+
RestClient.post('www.example.com', 'abc') # ===> Success
|
192
|
+
```
|
164
193
|
|
165
194
|
### Request with basic authentication
|
166
195
|
|
167
|
-
|
196
|
+
```ruby
|
197
|
+
stub_request(:get, "user:pass@www.example.com")
|
168
198
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
199
|
+
Net::HTTP.start('www.example.com') {|http|
|
200
|
+
req = Net::HTTP::Get.new('/')
|
201
|
+
req.basic_auth 'user', 'pass'
|
202
|
+
http.request(req)
|
203
|
+
} # ===> Success
|
204
|
+
```
|
174
205
|
|
175
206
|
### Matching uris using regular expressions
|
176
207
|
|
177
|
-
|
208
|
+
```ruby
|
209
|
+
stub_request(:any, /.*example.*/)
|
178
210
|
|
179
|
-
|
211
|
+
Net::HTTP.get('www.example.com', '/') # ===> Success
|
212
|
+
```
|
180
213
|
|
181
214
|
### Matching query params using hash
|
182
215
|
|
183
|
-
|
216
|
+
```ruby
|
217
|
+
stub_http_request(:get, "www.example.com").with(:query => {"a" => ["b", "c"]})
|
184
218
|
|
185
|
-
|
219
|
+
RestClient.get("http://www.example.com/?a[]=b&a[]=c") # ===> Success
|
220
|
+
```
|
186
221
|
|
187
222
|
### Matching partial query params using hash
|
188
223
|
|
189
|
-
|
224
|
+
```ruby
|
225
|
+
stub_http_request(:get, "www.example.com").with(:query => hash_including({"a" => ["b", "c"]}))
|
190
226
|
|
191
|
-
|
227
|
+
RestClient.get("http://www.example.com/?a[]=b&a[]=c&x=1") # ===> Success
|
228
|
+
```
|
192
229
|
|
193
230
|
### Stubbing with custom response
|
194
231
|
|
195
|
-
|
232
|
+
```ruby
|
233
|
+
stub_request(:any, "www.example.com").
|
234
|
+
to_return(:body => "abc", :status => 200, :headers => { 'Content-Length' => 3 })
|
196
235
|
|
197
|
-
|
236
|
+
Net::HTTP.get("www.example.com", '/') # ===> "abc"
|
237
|
+
```
|
198
238
|
|
199
239
|
### Response with body specified as IO object
|
200
240
|
|
201
|
-
|
241
|
+
```ruby
|
242
|
+
File.open('/tmp/response_body.txt', 'w') { |f| f.puts 'abc' }
|
202
243
|
|
203
|
-
|
244
|
+
stub_request(:any, "www.example.com").
|
245
|
+
to_return(:body => File.new('/tmp/response_body.txt'), :status => 200)
|
204
246
|
|
205
|
-
|
247
|
+
Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
|
248
|
+
```
|
206
249
|
|
207
250
|
### Response with custom status message
|
208
251
|
|
209
|
-
|
252
|
+
```ruby
|
253
|
+
stub_request(:any, "www.example.com").to_return(:status => [500, "Internal Server Error"])
|
210
254
|
|
211
|
-
|
212
|
-
|
255
|
+
req = Net::HTTP::Get.new("/")
|
256
|
+
Net::HTTP.start("www.example.com") {|http| http.request(req)}.message # ===> "Internal Server Error"
|
257
|
+
```
|
213
258
|
|
214
259
|
### Replaying raw responses recorded with `curl -is`
|
215
260
|
|
216
261
|
`curl -is www.example.com > /tmp/example_curl_-is_output.txt`
|
217
|
-
|
262
|
+
```ruby
|
263
|
+
raw_response_file = File.new("/tmp/example_curl_-is_output.txt")
|
264
|
+
```
|
218
265
|
|
219
266
|
from file
|
220
267
|
|
221
|
-
|
268
|
+
```ruby
|
269
|
+
stub_request(:get, "www.example.com").to_return(raw_response_file)
|
270
|
+
```
|
222
271
|
|
223
272
|
or string
|
224
273
|
|
225
|
-
|
274
|
+
```ruby
|
275
|
+
stub_request(:get, "www.example.com").to_return(raw_response_file.read)
|
276
|
+
```
|
226
277
|
|
227
278
|
### Responses dynamically evaluated from block
|
228
279
|
|
229
|
-
|
230
|
-
|
280
|
+
```ruby
|
281
|
+
stub_request(:any, 'www.example.net').
|
282
|
+
to_return { |request| {:body => request.body} }
|
231
283
|
|
232
|
-
|
284
|
+
RestClient.post('www.example.net', 'abc') # ===> "abc\n"
|
285
|
+
```
|
233
286
|
|
234
287
|
### Responses dynamically evaluated from lambda
|
235
288
|
|
236
|
-
|
237
|
-
|
289
|
+
```ruby
|
290
|
+
stub_request(:any, 'www.example.net').
|
291
|
+
to_return(lambda { |request| {:body => request.body} })
|
238
292
|
|
239
|
-
|
293
|
+
RestClient.post('www.example.net', 'abc') # ===> "abc\n"
|
294
|
+
```
|
240
295
|
|
241
296
|
### Dynamically evaluated raw responses recorded with `curl -is`
|
242
297
|
|
243
298
|
`curl -is www.example.com > /tmp/www.example.com.txt`
|
244
|
-
|
299
|
+
```ruby
|
300
|
+
stub_request(:get, "www.example.com").
|
301
|
+
to_return(lambda { |request| File.new("/tmp/#{request.uri.host.to_s}.txt" }))
|
302
|
+
```
|
245
303
|
|
246
304
|
### Responses with dynamically evaluated parts
|
247
305
|
|
248
|
-
|
249
|
-
|
306
|
+
```ruby
|
307
|
+
stub_request(:any, 'www.example.net').
|
308
|
+
to_return(:body => lambda { |request| request.body })
|
250
309
|
|
251
|
-
|
310
|
+
RestClient.post('www.example.net', 'abc') # ===> "abc\n"
|
311
|
+
```
|
252
312
|
|
253
313
|
### Rack responses
|
254
314
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
315
|
+
```ruby
|
316
|
+
class MyRackApp
|
317
|
+
def self.call(env)
|
318
|
+
[200, {}, ["Hello"]]
|
319
|
+
end
|
320
|
+
end
|
260
321
|
|
261
|
-
|
322
|
+
stub_request(:get, "www.example.com").to_rack(MyRackApp)
|
262
323
|
|
263
|
-
|
324
|
+
RestClient.post('www.example.com') # ===> "Hello"
|
325
|
+
```
|
264
326
|
|
265
327
|
### Raising errors
|
266
328
|
|
267
329
|
#### Exception declared by class
|
268
330
|
|
269
|
-
|
331
|
+
```ruby
|
332
|
+
stub_request(:any, 'www.example.net').to_raise(StandardError)
|
270
333
|
|
271
|
-
|
334
|
+
RestClient.post('www.example.net', 'abc') # ===> StandardError
|
335
|
+
```
|
272
336
|
|
273
337
|
#### or by exception instance
|
274
338
|
|
275
|
-
|
339
|
+
```ruby
|
340
|
+
stub_request(:any, 'www.example.net').to_raise(StandardError.new("some error"))
|
341
|
+
```
|
276
342
|
|
277
343
|
#### or by string
|
278
344
|
|
279
|
-
|
345
|
+
```ruby
|
346
|
+
stub_request(:any, 'www.example.net').to_raise("some error")
|
347
|
+
```
|
280
348
|
|
281
349
|
### Raising timeout errors
|
282
350
|
|
283
|
-
|
351
|
+
```ruby
|
352
|
+
stub_request(:any, 'www.example.net').to_timeout
|
284
353
|
|
285
|
-
|
354
|
+
RestClient.post('www.example.net', 'abc') # ===> RestClient::RequestTimeout
|
355
|
+
```
|
286
356
|
|
287
357
|
### Multiple responses for repeated requests
|
288
358
|
|
289
|
-
|
290
|
-
|
291
|
-
|
359
|
+
```ruby
|
360
|
+
stub_request(:get, "www.example.com").to_return({:body => "abc"}, {:body => "def"})
|
361
|
+
Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
|
362
|
+
Net::HTTP.get('www.example.com', '/') # ===> "def\n"
|
292
363
|
|
293
|
-
|
364
|
+
#after all responses are used the last response will be returned infinitely
|
294
365
|
|
295
|
-
|
366
|
+
Net::HTTP.get('www.example.com', '/') # ===> "def\n"
|
367
|
+
```
|
296
368
|
|
297
369
|
### Multiple responses using chained `to_return()`, `to_raise()` or `to_timeout` declarations
|
298
370
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
Net::HTTP.get('www.example.com', '/') # ===> "def\n"
|
305
|
-
Net::HTTP.get('www.example.com', '/') # ===> MyException raised
|
371
|
+
```ruby
|
372
|
+
stub_request(:get, "www.example.com").
|
373
|
+
to_return({:body => "abc"}).then. #then() is just a syntactic sugar
|
374
|
+
to_return({:body => "def"}).then.
|
375
|
+
to_raise(MyException)
|
306
376
|
|
307
|
-
|
377
|
+
Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
|
378
|
+
Net::HTTP.get('www.example.com', '/') # ===> "def\n"
|
379
|
+
Net::HTTP.get('www.example.com', '/') # ===> MyException raised
|
380
|
+
```
|
308
381
|
|
309
|
-
|
310
|
-
to_return({:body => "abc"}).times(2).then.
|
311
|
-
to_return({:body => "def"})
|
382
|
+
### Specifying number of times given response should be returned
|
312
383
|
|
313
|
-
|
314
|
-
|
315
|
-
|
384
|
+
```ruby
|
385
|
+
stub_request(:get, "www.example.com").
|
386
|
+
to_return({:body => "abc"}).times(2).then.
|
387
|
+
to_return({:body => "def"})
|
316
388
|
|
389
|
+
Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
|
390
|
+
Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
|
391
|
+
Net::HTTP.get('www.example.com', '/') # ===> "def\n"
|
392
|
+
```
|
317
393
|
|
318
394
|
### Real requests to network can be allowed or disabled
|
319
395
|
|
320
|
-
|
396
|
+
```ruby
|
397
|
+
WebMock.allow_net_connect!
|
321
398
|
|
322
|
-
|
399
|
+
stub_request(:any, "www.example.com").to_return(:body => "abc")
|
323
400
|
|
324
|
-
|
401
|
+
Net::HTTP.get('www.example.com', '/') # ===> "abc"
|
325
402
|
|
326
|
-
|
403
|
+
Net::HTTP.get('www.something.com', '/') # ===> /.+Something.+/
|
327
404
|
|
328
|
-
|
405
|
+
WebMock.disable_net_connect!
|
329
406
|
|
330
|
-
|
407
|
+
Net::HTTP.get('www.something.com', '/') # ===> Failure
|
408
|
+
```
|
331
409
|
|
332
410
|
### External requests can be disabled while allowing localhost
|
333
411
|
|
334
|
-
|
412
|
+
```ruby
|
413
|
+
WebMock.disable_net_connect!(:allow_localhost => true)
|
335
414
|
|
336
|
-
|
415
|
+
Net::HTTP.get('www.something.com', '/') # ===> Failure
|
337
416
|
|
338
|
-
|
417
|
+
Net::HTTP.get('localhost:9887', '/') # ===> Allowed. Perhaps to Selenium?
|
418
|
+
```
|
339
419
|
|
340
420
|
### External requests can be disabled while allowing any hostname or port or parts thereof
|
341
421
|
|
342
|
-
|
422
|
+
```ruby
|
423
|
+
WebMock.disable_net_connect!(:allow => "www.example.org:8080")
|
424
|
+
|
425
|
+
RestClient.get('www.something.com', '/') # ===> Failure
|
343
426
|
|
344
|
-
|
427
|
+
RestClient.get('www.example.org', '/') # ===> Failure.
|
345
428
|
|
346
|
-
|
429
|
+
RestClient.get('www.example.org:8080', '/') # ===> Allowed
|
347
430
|
|
348
|
-
|
431
|
+
WebMock.disable_net_connect!(:allow => /ample.org/)
|
349
432
|
|
350
|
-
|
433
|
+
WebMock.disable_net_connect!(:allow => [/ample.org/, /googl/])
|
351
434
|
|
352
|
-
|
435
|
+
RestClient.get('www.example.org', '/') # ===> Allowed
|
436
|
+
```
|
353
437
|
|
354
438
|
## Connecting on Net::HTTP.start
|
355
439
|
|
@@ -366,112 +450,136 @@ so when there is no request, `Net::HTTP.start` doesn't do anything.
|
|
366
450
|
To workaround this issue, WebMock offers `:net_http_connect_on_start` option,
|
367
451
|
which can be passed to `WebMock.allow_net_connect!` and `WebMock#disable_net_connect!` methods, i.e.
|
368
452
|
|
369
|
-
|
453
|
+
```ruby
|
454
|
+
WebMock.allow_net_connect!(:net_http_connect_on_start => true)
|
455
|
+
```
|
370
456
|
|
371
457
|
This forces WebMock Net::HTTP adapter to always connect on `Net::HTTP.start`.
|
372
458
|
|
373
459
|
## Setting Expectations
|
374
460
|
|
375
461
|
### Setting expectations in Test::Unit
|
376
|
-
require 'webmock/test_unit'
|
377
462
|
|
378
|
-
|
463
|
+
```ruby
|
464
|
+
require 'webmock/test_unit'
|
379
465
|
|
380
|
-
|
381
|
-
req = Net::HTTP::Post.new(uri.path)
|
382
|
-
req['Content-Length'] = 3
|
383
|
-
res = Net::HTTP.start(uri.host, uri.port) {|http|
|
384
|
-
http.request(req, 'abc')
|
385
|
-
}
|
466
|
+
stub_request(:any, "www.example.com")
|
386
467
|
|
387
|
-
|
388
|
-
|
468
|
+
uri = URI.parse('http://www.example.com/')
|
469
|
+
req = Net::HTTP::Post.new(uri.path)
|
470
|
+
req['Content-Length'] = 3
|
389
471
|
|
390
|
-
|
472
|
+
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
473
|
+
http.request(req, 'abc')
|
474
|
+
end
|
391
475
|
|
392
|
-
|
476
|
+
assert_requested :post, "http://www.example.com",
|
477
|
+
:headers => {'Content-Length' => 3}, :body => "abc", :times => 1 # ===> Success
|
478
|
+
|
479
|
+
assert_not_requested :get, "http://www.something.com" # ===> Success
|
480
|
+
|
481
|
+
assert_requested(:post, "http://www.example.com", :times => 1) { |req| req.body == "abc" }
|
482
|
+
```
|
393
483
|
|
394
484
|
### Expecting real (not stubbed) requests
|
395
485
|
|
396
|
-
|
486
|
+
```ruby
|
487
|
+
WebMock.allow_net_connect!
|
397
488
|
|
398
|
-
|
489
|
+
Net::HTTP.get('www.example.com', '/') # ===> Success
|
399
490
|
|
400
|
-
|
491
|
+
assert_requested :get, "http://www.example.com" # ===> Success
|
492
|
+
```
|
401
493
|
|
402
494
|
### Setting expectations in Test::Unit on the stub
|
403
495
|
|
404
|
-
|
405
|
-
|
496
|
+
```ruby
|
497
|
+
stub_get = stub_request(:get, "www.example.com")
|
498
|
+
stub_post = stub_request(:post, "www.example.com")
|
406
499
|
|
407
|
-
|
500
|
+
Net::HTTP.get('www.example.com', '/')
|
408
501
|
|
409
|
-
|
410
|
-
|
502
|
+
assert_requested(stub_get)
|
503
|
+
assert_not_requested(stub_post)
|
504
|
+
```
|
411
505
|
|
412
506
|
|
413
507
|
### Setting expectations in RSpec on `WebMock` module
|
414
508
|
This style is borrowed from [fakeweb-matcher](http://github.com/freelancing-god/fakeweb-matcher)
|
415
509
|
|
416
|
-
|
510
|
+
```ruby
|
511
|
+
require 'webmock/rspec'
|
417
512
|
|
418
|
-
|
513
|
+
WebMock.should have_requested(:get, "www.example.com").
|
514
|
+
with(:body => "abc", :headers => {'Content-Length' => 3}).twice
|
419
515
|
|
420
|
-
|
516
|
+
WebMock.should_not have_requested(:get, "www.something.com")
|
421
517
|
|
422
|
-
|
518
|
+
WebMock.should have_requested(:post, "www.example.com").with { |req| req.body == "abc" }
|
423
519
|
|
424
|
-
|
520
|
+
WebMock.should have_requested(:get, "www.example.com").with(:query => {"a" => ["b", "c"]})
|
425
521
|
|
426
|
-
|
522
|
+
WebMock.should have_requested(:get, "www.example.com").
|
523
|
+
with(:query => hash_including({"a" => ["b", "c"]}))
|
427
524
|
|
428
|
-
|
429
|
-
|
525
|
+
WebMock.should have_requested(:get, "www.example.com").
|
526
|
+
with(:body => {"a" => ["b", "c"]}, :headers => {'Content-Type' => 'application/json'})
|
527
|
+
```
|
430
528
|
|
431
529
|
### Setting expectations in RSpec with `a_request`
|
432
530
|
|
433
|
-
|
531
|
+
```ruby
|
532
|
+
a_request(:post, "www.example.com").
|
533
|
+
with(:body => "abc", :headers => {'Content-Length' => 3}).should have_been_made.once
|
434
534
|
|
435
|
-
|
535
|
+
a_request(:post, "www.something.com").should have_been_made.times(3)
|
436
536
|
|
437
|
-
|
537
|
+
a_request(:any, "www.example.com").should_not have_been_made
|
438
538
|
|
439
|
-
|
539
|
+
a_request(:post, "www.example.com").with { |req| req.body == "abc" }.should have_been_made
|
440
540
|
|
441
|
-
|
541
|
+
a_request(:get, "www.example.com").with(:query => {"a" => ["b", "c"]}).should have_been_made
|
442
542
|
|
443
|
-
|
543
|
+
a_request(:get, "www.example.com").
|
544
|
+
with(:query => hash_including({"a" => ["b", "c"]})).should have_been_made
|
444
545
|
|
445
|
-
|
446
|
-
|
546
|
+
a_request(:post, "www.example.com").
|
547
|
+
with(:body => {"a" => ["b", "c"]}, :headers => {'Content-Type' => 'application/json'}).
|
548
|
+
should have_been_made
|
549
|
+
```
|
447
550
|
|
448
551
|
### Setting expectations in RSpec on the stub
|
449
552
|
|
450
|
-
|
451
|
-
|
452
|
-
|
553
|
+
```ruby
|
554
|
+
stub = stub_request(:get, "www.example.com")
|
555
|
+
# ... make requests ...
|
556
|
+
stub.should have_been_requested
|
557
|
+
```
|
453
558
|
|
454
559
|
## Clearing stubs and request history
|
455
560
|
|
456
561
|
If you want to reset all current stubs and history of requests use `WebMock.reset!`
|
457
562
|
|
458
|
-
|
563
|
+
```ruby
|
564
|
+
stub_request(:any, "www.example.com")
|
459
565
|
|
460
|
-
|
566
|
+
Net::HTTP.get('www.example.com', '/') # ===> Success
|
461
567
|
|
462
|
-
|
568
|
+
WebMock.reset!
|
463
569
|
|
464
|
-
|
570
|
+
Net::HTTP.get('www.example.com', '/') # ===> Failure
|
465
571
|
|
466
|
-
|
572
|
+
assert_not_requested :get, "www.example.com" # ===> Success
|
573
|
+
```
|
467
574
|
|
468
575
|
## Disabling and enabling WebMock or only some http client adapters
|
469
576
|
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
577
|
+
```ruby
|
578
|
+
WebMock.disable! #disable WebMock (all adapters)
|
579
|
+
WebMock.disable!(:except => [:net_http]) #disable WebMock for all libs except Net::HTTP
|
580
|
+
WebMock.enable! #enable WebMock (all adapters)
|
581
|
+
WebMock.enable!(:except => [:patron]) #enable WebMock for all libs except Patron
|
582
|
+
```
|
475
583
|
|
476
584
|
## Matching requests
|
477
585
|
|
@@ -487,10 +595,12 @@ An executed request matches stubbed request if it passes following criteria:
|
|
487
595
|
|
488
596
|
Always the last declared stub matching the request will be applied i.e:
|
489
597
|
|
490
|
-
|
491
|
-
|
598
|
+
```ruby
|
599
|
+
stub_request(:get, "www.example.com").to_return(:body => "abc")
|
600
|
+
stub_request(:get, "www.example.com").to_return(:body => "def")
|
492
601
|
|
493
|
-
|
602
|
+
Net::HTTP.get('www.example.com', '/') # ====> "def"
|
603
|
+
```
|
494
604
|
|
495
605
|
## Matching URIs
|
496
606
|
|
@@ -498,51 +608,55 @@ WebMock will match all different representations of the same URI.
|
|
498
608
|
|
499
609
|
I.e all the following representations of the URI are equal:
|
500
610
|
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
611
|
+
```ruby
|
612
|
+
"www.example.com"
|
613
|
+
"www.example.com/"
|
614
|
+
"www.example.com:80"
|
615
|
+
"www.example.com:80/"
|
616
|
+
"http://www.example.com"
|
617
|
+
"http://www.example.com/"
|
618
|
+
"http://www.example.com:80"
|
619
|
+
"http://www.example.com:80/"
|
620
|
+
```
|
509
621
|
|
510
622
|
The following URIs with basic authentication are also equal for WebMock
|
511
623
|
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
624
|
+
```ruby
|
625
|
+
"a b:pass@www.example.com"
|
626
|
+
"a b:pass@www.example.com/"
|
627
|
+
"a b:pass@www.example.com:80"
|
628
|
+
"a b:pass@www.example.com:80/"
|
629
|
+
"http://a b:pass@www.example.com"
|
630
|
+
"http://a b:pass@www.example.com/"
|
631
|
+
"http://a b:pass@www.example.com:80"
|
632
|
+
"http://a b:pass@www.example.com:80/"
|
633
|
+
"a%20b:pass@www.example.com"
|
634
|
+
"a%20b:pass@www.example.com/"
|
635
|
+
"a%20b:pass@www.example.com:80"
|
636
|
+
"a%20b:pass@www.example.com:80/"
|
637
|
+
"http://a%20b:pass@www.example.com"
|
638
|
+
"http://a%20b:pass@www.example.com/"
|
639
|
+
"http://a%20b:pass@www.example.com:80"
|
640
|
+
"http://a%20b:pass@www.example.com:80/"
|
641
|
+
```
|
528
642
|
|
529
643
|
or these
|
530
644
|
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
645
|
+
```ruby
|
646
|
+
"www.example.com/my path/?a=my param&b=c"
|
647
|
+
"www.example.com/my%20path/?a=my%20param&b=c"
|
648
|
+
"www.example.com:80/my path/?a=my param&b=c"
|
649
|
+
"www.example.com:80/my%20path/?a=my%20param&b=c"
|
650
|
+
"http://www.example.com/my path/?a=my param&b=c"
|
651
|
+
"http://www.example.com/my%20path/?a=my%20param&b=c"
|
652
|
+
"http://www.example.com:80/my path/?a=my param&b=c"
|
653
|
+
"http://www.example.com:80/my%20path/?a=my%20param&b=c"
|
654
|
+
```
|
540
655
|
|
541
656
|
If you provide Regexp to match URI, WebMock will try to match it against every valid form of the same url.
|
542
657
|
|
543
658
|
I.e `/.*my param.*/` will match `www.example.com/my%20path` because it is equivalent of `www.example.com/my path`
|
544
659
|
|
545
|
-
|
546
660
|
## Matching headers
|
547
661
|
|
548
662
|
WebMock will match request headers against stubbed request headers in the following situations:
|
@@ -571,15 +685,19 @@ To record your application's real HTTP interactions and replay them later in tes
|
|
571
685
|
|
572
686
|
####WebMock can invoke callbacks stubbed or real requests:
|
573
687
|
|
574
|
-
|
575
|
-
|
576
|
-
|
688
|
+
```ruby
|
689
|
+
WebMock.after_request do |request_signature, response|
|
690
|
+
puts "Request #{request_signature} was made and #{response} was returned"
|
691
|
+
end
|
692
|
+
```
|
577
693
|
|
578
694
|
#### invoke callbacks for real requests only and except requests made with Patron
|
579
695
|
|
580
|
-
|
581
|
-
|
582
|
-
|
696
|
+
```ruby
|
697
|
+
WebMock.after_request(:except => [:patron], :real_requests_only => true) do |req_signature, response|
|
698
|
+
puts "Request #{req_signature} was made and #{response} was returned"
|
699
|
+
end
|
700
|
+
```
|
583
701
|
|
584
702
|
## Bugs and Issues
|
585
703
|
|
@@ -718,10 +836,17 @@ People who submitted patches and new features or suggested improvements. Many th
|
|
718
836
|
* Pavel Forkert
|
719
837
|
* Jordi Massaguer Pla
|
720
838
|
* Jake Benilov
|
721
|
-
*
|
839
|
+
* Tom Beauvais
|
722
840
|
* Mokevnin Kirill
|
723
841
|
* Alex Grant
|
724
842
|
* Lucas Dohmen
|
843
|
+
* Bastien Vaucher
|
844
|
+
* Joost Baaij
|
845
|
+
* Joel Chippindale
|
846
|
+
* Murahashi Sanemat Kenichi
|
847
|
+
* Tim Kurvers
|
848
|
+
* Ilya Vassilevsky
|
849
|
+
* gotwalt
|
725
850
|
|
726
851
|
For a full list of contributors you can visit the
|
727
852
|
[contributors](https://github.com/bblimke/webmock/contributors) page.
|