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