Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 369 lines (227 sloc) 12.316 kb
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
1 WebMock
2 =======
3
4 Library for stubbing HTTP requests and setting expectations on HTTP requests in Ruby.
5
6 Features
7 --------
8
9 * Stubbing HTTP requests at low Net::HTTP level (no need to change tests when you change HTTP lib interface)
10 * Setting and verifying expectations on HTTP requests
11 * Matching requests based on method, URI, headers and body
12 * Smart matching of the same URIs in different representations (also encoded and non encoded forms)
13 * Smart matching of the same headers in different representations.
14 * Support for Test::Unit and RSpec (and can be easily extended to other frameworks)
15 * Support for Net::HTTP and other http libraries based on Net::HTTP (i.e RightHttpConnection, rest-client, HTTParty)
32c653c Replaced google with example in README
Bartosz Blimke authored
16 * Support for HTTPClient library (both sync and async requests)
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
17 * Easy to extend to other HTTP libraries except Net::HTTP
18
19 Installation
20 ------------
21
22 gem install webmock --source http://gemcutter.org
23
24 In your `test/test_helper.rb` add these two lines:
25
26 require 'webmock/test_unit'
27
28 include WebMock
29
30 or if you use RSpec add these lines to `spec/spec_helper`:
31
32 require 'webmock/rspec'
33
34 include WebMock
35
feb8ba5 Updated version to 0.7.3
Bartosz Blimke authored
36 You can also use WebMock without RSpec or Test::Unit support:
3ca443e WebMock module has to be included manually and is not included by RSpec ...
Bartosz Blimke authored
37
38 require 'webmock'
39
40 include WebMock
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
41
42 ## Examples
43
44
45
46 ## Stubbing
47
48
49 ### Stubbed request based on uri only and with the default response
50
32c653c Replaced google with example in README
Bartosz Blimke authored
51 stub_request(:any, "www.example.com")
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
52
32c653c Replaced google with example in README
Bartosz Blimke authored
53 Net::HTTP.get("www.example.com", "/") # ===> Success
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
54
55 ### Stubbing requests based on method, uri, body and headers
56
32c653c Replaced google with example in README
Bartosz Blimke authored
57 stub_request(:post, "www.example.com").with(:body => "abc", :headers => { 'Content-Length' => 3 })
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
58
32c653c Replaced google with example in README
Bartosz Blimke authored
59 uri = URI.parse("http://www.example.com/")
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
60 req = Net::HTTP::Post.new(uri.path)
61 req['Content-Length'] = 3
62 res = Net::HTTP.start(uri.host, uri.port) {|http|
63 http.request(req, "abc")
64 } # ===> Success
65
5313e02 Added version 0.9.0 features to CHANGELOG and README
Bartosz Blimke authored
66 ### Matching request body and headers against regular expressions
67
68 stub_request(:post, "www.example.com").
69 with(:body => /^.*world$/, :headers => {"Content-Type" => /image\/.+/}).to_return(:body => "abc")
70
71 uri = URI.parse('http://www.example.com/')
72 req = Net::HTTP::Post.new(uri.path)
73 req['Content-Type'] = 'image/png'
74 res = Net::HTTP.start(uri.host, uri.port) {|http|
75 http.request(req, 'hello world')
76 } # ===> Success
77
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
78 ### Matching custom request headers
79
32c653c Replaced google with example in README
Bartosz Blimke authored
80 stub_request(:any, "www.example.com").
5313e02 Added version 0.9.0 features to CHANGELOG and README
Bartosz Blimke authored
81 with(:headers=>{ 'Header-Name' => 'Header-Value' }).to_return(:body => "abc", :status => 200)
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
82
32c653c Replaced google with example in README
Bartosz Blimke authored
83 uri = URI.parse('http://www.example.com/')
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
84 req = Net::HTTP::Post.new(uri.path)
85 req['Header-Name'] = 'Header-Value'
86 res = Net::HTTP.start(uri.host, uri.port) {|http|
87 http.request(req, 'abc')
88 } # ===> Success
89
5313e02 Added version 0.9.0 features to CHANGELOG and README
Bartosz Blimke authored
90 ### Matching requests against provided block
91
92 stub_request(:post, "www.example.com").with { |request| request.body == "abc" }.to_return(:body => "abc")
93 RestClient.post('www.example.com', 'abc') # ===> "abc\n"
94
95 ### Request with basic authentication
96
97 stub_request(:get, "user:pass@www.example.com")
98
99 Net::HTTP.start('www.example.com') {|http|
100 req = Net::HTTP::Get.new('/')
101 req.basic_auth 'user', 'pass'
102 http.request(req)
103 } # ===> Success
104
105 ### Matching uris using regular expressions
106
107 stub_request(:any, /.*example.*/)
108
109 Net::HTTP.get('www.example.com', '/') # ===> Success
110
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
111 ### Stubbing with custom response
112
32c653c Replaced google with example in README
Bartosz Blimke authored
113 stub_request(:any, "www.example.com").to_return(:body => "abc", :status => 200, :headers => { 'Content-Length' => 3 } )
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
114
32c653c Replaced google with example in README
Bartosz Blimke authored
115 Net::HTTP.get("www.example.com", '/') # ===> "abc"
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
116
32c653c Replaced google with example in README
Bartosz Blimke authored
117 ### Custom response with body specified as IO object
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
118
119 File.open('/tmp/response_body.txt', 'w') { |f| f.puts 'abc' }
120
32c653c Replaced google with example in README
Bartosz Blimke authored
121 stub_request(:any, "www.example.com").to_return(:body => File.new('/tmp/response_body.txt'), :status => 200)
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
122
32c653c Replaced google with example in README
Bartosz Blimke authored
123 Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
5313e02 Added version 0.9.0 features to CHANGELOG and README
Bartosz Blimke authored
124
125 ### Replaying raw responses recorded with `curl -is`
126
127 `curl -is www.example.com > /tmp/example_curl_-is_output.txt`
128 raw_response_file = File.new("/tmp/example_curl_-is_output.txt")
129
130 from file
131
132 stub_request(:get, "www.example.com").to_return(raw_response_file)
133
134 or string
135
136 stub_request(:get, "www.example.com").to_return(raw_response_file.read)
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
137
4e0568a Added information about dynamic responses to README
Bartosz Blimke authored
138 ### Custom response with dynamically evaluated response
139
140 stub_request(:any, 'www.example.net').
141 to_return(:body => lambda { |request| request.body })
142
143 RestClient.post('www.example.net', 'abc') # ===> "abc\n"
144
5313e02 Added version 0.9.0 features to CHANGELOG and README
Bartosz Blimke authored
145 ### Multiple responses for repeated requests
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
146
5313e02 Added version 0.9.0 features to CHANGELOG and README
Bartosz Blimke authored
147 stub_request(:get, "www.example.com").to_return({:body => "abc"}, {:body => "def"})
148 Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
149 Net::HTTP.get('www.example.com', '/') # ===> "def\n"
150
151 #after all responses are used the last response will be returned infinitely
152
153 Net::HTTP.get('www.example.com', '/') # ===> "def\n"
bb41263 Improved section about basic authentication support in readme.
Bartosz Blimke authored
154
5313e02 Added version 0.9.0 features to CHANGELOG and README
Bartosz Blimke authored
155 ### Multiple responses using chained `to_return()` or `to_raise()` declarations
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
156
5313e02 Added version 0.9.0 features to CHANGELOG and README
Bartosz Blimke authored
157 stub_request(:get, "www.example.com").
158 to_return({:body => "abc"}).then. #then() just is a syntactic sugar
159 to_return({:body => "def"}).then.
160 to_raise(MyException)
161 Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
162 Net::HTTP.get('www.example.com', '/') # ===> "def\n"
163 Net::HTTP.get('www.example.com', '/') # ===> MyException raised
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
164
5313e02 Added version 0.9.0 features to CHANGELOG and README
Bartosz Blimke authored
165 ### Specifying number of times given response should be returned
166
167 stub_request(:get, "www.example.com").
168 to_return({:body => "abc"}).times(2).then.
169 to_return({:body => "def"})
170
171 Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
172 Net::HTTP.get('www.example.com', '/') # ===> "abc\n"
173 Net::HTTP.get('www.example.com', '/') # ===> "def\n"
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
174
175
176 ### Real requests to network can be allowed or disabled
177
178 WebMock.allow_net_connect!
179
32c653c Replaced google with example in README
Bartosz Blimke authored
180 stub_request(:any, "www.example.com").to_return(:body => "abc")
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
181
32c653c Replaced google with example in README
Bartosz Blimke authored
182 Net::HTTP.get('www.example.com', '/') # ===> "abc"
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
183
184 Net::HTTP.get('www.something.com', '/') # ===> /.+Something.+/
185
186 WebMock.disable_net_connect!
187
188 Net::HTTP.get('www.something.com', '/') # ===> Failure
189
190
191 ## Setting Expectations
192
193 ### Setting expectations in Test::Unit
194 require 'webmock/test_unit'
195
32c653c Replaced google with example in README
Bartosz Blimke authored
196 stub_request(:any, "www.example.com")
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
197
32c653c Replaced google with example in README
Bartosz Blimke authored
198 uri = URI.parse('http://www.example.com/')
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
199 req = Net::HTTP::Post.new(uri.path)
200 req['Content-Length'] = 3
201 res = Net::HTTP.start(uri.host, uri.port) {|http|
202 http.request(req, 'abc')
203 }
204
32c653c Replaced google with example in README
Bartosz Blimke authored
205 assert_requested :post, "http://www.example.com",
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
206 :headers => {'Content-Length' => 3}, :body => "abc", :times => 1 # ===> Success
207
208 assert_not_requested :get, "http://www.something.com" # ===> Success
209
5313e02 Added version 0.9.0 features to CHANGELOG and README
Bartosz Blimke authored
210 assert_requested(:post, "http://www.example.com", :times => 1) { |req| req.body == "abc" }
211
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
212 ### Expecting real (not stubbed) requests
213
214 WebMock.allow_net_connect!
215
32c653c Replaced google with example in README
Bartosz Blimke authored
216 Net::HTTP.get('www.example.com', '/') # ===> Success
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
217
32c653c Replaced google with example in README
Bartosz Blimke authored
218 assert_requested :get, "http://www.example.com" # ===> Success
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
219
220
221 ### Setting expectations in RSpec
222 This style is borrowed from [fakeweb-matcher](http://github.com/freelancing-god/fakeweb-matcher)
223
224 require 'webmock/rspec'
225
32c653c Replaced google with example in README
Bartosz Blimke authored
226 WebMock.should have_requested(:get, "www.example.com").with(:body => "abc", :headers => {'Content-Length' => 3}).twice
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
227
228 WebMock.should_not have_requested(:get, "www.something.com")
5313e02 Added version 0.9.0 features to CHANGELOG and README
Bartosz Blimke authored
229
230 WebMock.should have_requested(:post, "www.example.com").with { |req| req.body == "abc" }
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
231
232 ### Different way of setting expectations in RSpec
233
32c653c Replaced google with example in README
Bartosz Blimke authored
234 request(:post, "www.example.com").with(:body => "abc", :headers => {'Content-Length' => 3}).should have_been_made.once
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
235
236 request(:post, "www.something.com").should have_been_made.times(3)
237
238 request(:any, "www.example.com").should_not have_been_made
239
5313e02 Added version 0.9.0 features to CHANGELOG and README
Bartosz Blimke authored
240 request(:post, "www.example.com").with { |req| req.body == "abc" }.should have_been_made
241
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
242 ## Clearing stubs and request history
243
244 If you want to reset all current stubs and history of requests use `WebMock.reset_webmock`
245
32c653c Replaced google with example in README
Bartosz Blimke authored
246 stub_request(:any, "www.example.com")
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
247
32c653c Replaced google with example in README
Bartosz Blimke authored
248 Net::HTTP.get('www.example.com', '/') # ===> Success
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
249
250 reset_webmock
251
32c653c Replaced google with example in README
Bartosz Blimke authored
252 Net::HTTP.get('www.example.com', '/') # ===> Failure
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
253
32c653c Replaced google with example in README
Bartosz Blimke authored
254 assert_not_requested :get, "www.example.com" # ===> Success
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
255
256
257 ## Matching requests
258
259 An executed request matches stubbed request if it passes following criteria:
260
4306efa Ability to register and expect requests with empty body.
Bartosz Blimke authored
261 When request URI matches stubbed request URI string or Regexp pattern<br/>
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
262 And request method is the same as stubbed request method or stubbed request method is :any<br/>
4306efa Ability to register and expect requests with empty body.
Bartosz Blimke authored
263 And request body is the same as stubbed request body or stubbed request body is not specified<br/>
264 And request headers match stubbed request headers, or stubbed request headers match a subset of request headers, or stubbed request headers are not specified
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
265
266 ## Precedence of stubs
267
268 Always the last declared stub matching the request will be applied i.e:
269
32c653c Replaced google with example in README
Bartosz Blimke authored
270 stub_request(:get, "www.example.com").to_return(:body => "abc")
271 stub_request(:get, "www.example.com").to_return(:body => "def")
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
272
32c653c Replaced google with example in README
Bartosz Blimke authored
273 Net::HTTP.get('www.example.com', '/') # ====> "def"
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
274
275 ## Matching URIs
276
277 WebMock will match all different representations of the same URI.
278
279 I.e all the following representations of the URI are equal:
280
32c653c Replaced google with example in README
Bartosz Blimke authored
281 "www.example.com"
282 "www.example.com/"
283 "www.example.com:80"
284 "www.example.com:80/"
285 "http://www.example.com"
286 "http://www.example.com/"
287 "http://www.example.com:80"
288 "http://www.example.com:80/"
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
289
290 The following URIs with basic authentication are also equal for WebMock
291
32c653c Replaced google with example in README
Bartosz Blimke authored
292 "a b:pass@www.example.com"
293 "a b:pass@www.example.com/"
294 "a b:pass@www.example.com:80"
295 "a b:pass@www.example.com:80/"
296 "http://a b:pass@www.example.com"
297 "http://a b:pass@www.example.com/"
298 "http://a b:pass@www.example.com:80"
299 "http://a b:pass@www.example.com:80/"
300 "a%20b:pass@www.example.com"
301 "a%20b:pass@www.example.com/"
302 "a%20b:pass@www.example.com:80"
303 "a%20b:pass@www.example.com:80/"
304 "http://a%20b:pass@www.example.com"
305 "http://a%20b:pass@www.example.com/"
306 "http://a%20b:pass@www.example.com:80"
307 "http://a%20b:pass@www.example.com:80/"
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
308
309 or these
310
78414b7 Improved examples with equality of URIs with the same parameters
Bartosz Blimke authored
311 "www.example.com/my path/?a=my param&b=c"
312 "www.example.com/my%20path/?a=my%20param&b=c"
313 "www.example.com:80/my path/?a=my param&b=c"
314 "www.example.com:80/my%20path/?a=my%20param&b=c"
315 "http://www.example.com/my path/?a=my param&b=c"
316 "http://www.example.com/my%20path/?a=my%20param&b=c"
317 "http://www.example.com:80/my path/?a=my param&b=c"
318 "http://www.example.com:80/my%20path/?a=my%20param&b=c"
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
319
320
321 If you provide Regexp to match URI, WebMock will try to match it against every valid form of the same url.
322
78414b7 Improved examples with equality of URIs with the same parameters
Bartosz Blimke authored
323 I.e `/.*my param.*/` will match `www.example.com/my%20path` because it is equivalent of `www.example.com/my path`
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
324
325
326 ## Matching headers
327
328 WebMock will match request headers against stubbed request headers in the following situations:
329
330 1. Stubbed request has headers specified and request headers are the same as stubbed headers <br/>
331 i.e stubbed headers: `{ 'Header1' => 'Value1', 'Header1' => 'Value1' }`, requested: `{ 'Header1' => 'Value1', 'Header1' => 'Value1' }`
332
333 2. Stubbed request has headers specified and stubbed request headers are a subset of request headers <br/>
334 i.e stubbed headers: `{ 'Header1' => 'Value1' }`, requested: `{ 'Header1' => 'Value1', 'Header1' => 'Value1' }`
335
336 3. Stubbed request has no headers <br/>
337 i.e stubbed headers: `nil`, requested: `{ 'Header1' => 'Value1', 'Header1' => 'Value1' }`
338
339 WebMock normalises headers and treats all forms of same headers as equal:
340 i.e the following two sets of headers are equal:
341
342 `{ "Header1" => "value1", :content_length => 123, :X_CuStOm_hEAder => :value }`
343
344 `{ :header1 => "value1", "Content-Length" => 123, "x-cuSTOM-HeAder" => "value" }`
345
346
347 ## Bugs and Issues
348
349 Please submit them here [http://github.com/bblimke/webmock/issues](http://github.com/bblimke/webmock/issues)
350
351 ## Suggestions
352
353 If you have any suggestions on how to improve WebMock please send an email to the mailing list [groups.google.com/group/webmock-users](http://groups.google.com/group/webmock-users)
354
355 I'm particularly interested in how the DSL could be improved.
356
357 ## Credits
358
359 Thanks to my fellow [Bambinos](http://new-bamboo.co.uk/) for all the great suggestions!
360
361 Thank you Fakeweb! This library was inspired by [FakeWeb](fakeweb.rubyforge.org).
362 I took couple of solutions from that project. I also copied some code i.e Net:HTTP adapter.
363 Fakeweb architecture unfortunately didn't allow me to extend it easily with the features I needed.
364 I also preferred some things to work differently i.e request stub precedence.
365
366 ## Copyright
367
368 Copyright 2009 Bartosz Blimke. See LICENSE for details.
Something went wrong with that request. Please try again.