Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 302 lines (183 sloc) 9.783 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)
16 * Easy to extend to other HTTP libraries except Net::HTTP
17
18 Installation
19 ------------
20
21 gem install webmock --source http://gemcutter.org
22
23 In your `test/test_helper.rb` add these two lines:
24
25 require 'webmock/test_unit'
26
27 include WebMock
28
29 or if you use RSpec add these lines to `spec/spec_helper`:
30
31 require 'webmock/rspec'
32
33 include WebMock
34
feb8ba5 Updated version to 0.7.3
Bartosz Blimke authored
35 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
36
37 require 'webmock'
38
39 include WebMock
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
40
41 ## Examples
42
43
44
45 ## Stubbing
46
47
48 ### Stubbed request based on uri only and with the default response
49
50 stub_request(:any, "www.google.com")
51
52 Net::HTTP.get("www.google.com", "/") # ===> Success
53
54 ### Stubbing requests based on method, uri, body and headers
55
56 stub_request(:post, "www.google.com").with(:body => "abc", :headers => { 'Content-Length' => 3 })
57
58 uri = URI.parse("http://www.google.com/")
59 req = Net::HTTP::Post.new(uri.path)
60 req['Content-Length'] = 3
61 res = Net::HTTP.start(uri.host, uri.port) {|http|
62 http.request(req, "abc")
63 } # ===> Success
64
65 ### Matching custom request headers
66
67 stub_request(:any, "www.google.com").
68 with( :headers=>{ 'Header-Name' => 'Header-Value' } ).to_return(:body => "abc", :status => 200)
69
70 uri = URI.parse('http://www.google.com/')
71 req = Net::HTTP::Post.new(uri.path)
72 req['Header-Name'] = 'Header-Value'
73 res = Net::HTTP.start(uri.host, uri.port) {|http|
74 http.request(req, 'abc')
75 } # ===> Success
76
77 ### Stubbing with custom response
78
79 stub_request(:any, "www.google.com").to_return(:body => "abc", :status => 200, :headers => { 'Content-Length' => 3 } )
80
81 Net::HTTP.get("www.google.com", '/') # ===> "abc"
82
83 ### Custom response with body specified as a path to file
84
85 File.open('/tmp/response_body.txt', 'w') { |f| f.puts 'abc' }
86
87 stub_request(:any, "www.google.com").to_return(:body => "/tmp/response_body.txt", :status => 200)
88
89 Net::HTTP.get('www.google.com', '/') # ===> "abc\n"
90
4e0568a Added information about dynamic responses to README
Bartosz Blimke authored
91 ### Custom response with dynamically evaluated response
92
93 stub_request(:any, 'www.example.net').
94 to_return(:body => lambda { |request| request.body })
95
96 RestClient.post('www.example.net', 'abc') # ===> "abc\n"
97
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
98 ### Request with basic authentication
99
bb41263 Improved section about basic authentication support in readme.
Bartosz Blimke authored
100 stub_request(:get, "user:pass@www.google.com")
101
102 Net::HTTP.start('www.google.com') {|http|
103 req = Net::HTTP::Get.new('/')
104 req.basic_auth 'user', 'pass'
105 http.request(req)
106 } # ===> Success
95e8298 Revert "WebMock module has to be included manually and is not included b...
Bartosz Blimke authored
107
108 ### Matching uris using regular expressions
109
110 stub_request(:any, /.*google.*/)
111
112 Net::HTTP.get('www.google.com', '/') # ===> Success
113
114 ### Real requests to network can be allowed or disabled
115
116 WebMock.allow_net_connect!
117
118 stub_request(:any, "www.google.com").to_return(:body => "abc")
119
120 Net::HTTP.get('www.google.com', '/') # ===> "abc"
121
122 Net::HTTP.get('www.something.com', '/') # ===> /.+Something.+/
123
124 WebMock.disable_net_connect!
125
126 Net::HTTP.get('www.something.com', '/') # ===> Failure
127
128
129 ## Setting Expectations
130
131 ### Setting expectations in Test::Unit
132 require 'webmock/test_unit'
133
134 stub_request(:any, "www.google.com")
135
136 uri = URI.parse('http://www.google.com/')
137 req = Net::HTTP::Post.new(uri.path)
138 req['Content-Length'] = 3
139 res = Net::HTTP.start(uri.host, uri.port) {|http|
140 http.request(req, 'abc')
141 }
142
143 assert_requested :post, "http://www.google.com",
144 :headers => {'Content-Length' => 3}, :body => "abc", :times => 1 # ===> Success
145
146 assert_not_requested :get, "http://www.something.com" # ===> Success
147
148 ### Expecting real (not stubbed) requests
149
150 WebMock.allow_net_connect!
151
152 Net::HTTP.get('www.google.com', '/') # ===> Success
153
154 assert_requested :get, "http://www.google.com" # ===> Success
155
156
157 ### Setting expectations in RSpec
158 This style is borrowed from [fakeweb-matcher](http://github.com/freelancing-god/fakeweb-matcher)
159
160 require 'webmock/rspec'
161
162 WebMock.should have_requested(:get, "www.google.com").with(:body => "abc", :headers => {'Content-Length' => 3}).twice
163
164 WebMock.should_not have_requested(:get, "www.something.com")
165
166 ### Different way of setting expectations in RSpec
167
168 request(:post, "www.google.com").with(:body => "abc", :headers => {'Content-Length' => 3}).should have_been_made.once
169
170 request(:post, "www.something.com").should have_been_made.times(3)
171
172 request(:any, "www.example.com").should_not have_been_made
173
174
175 ## Clearing stubs and request history
176
177 If you want to reset all current stubs and history of requests use `WebMock.reset_webmock`
178
179 stub_request(:any, "www.google.com")
180
181 Net::HTTP.get('www.google.com', '/') # ===> Success
182
183 reset_webmock
184
185 Net::HTTP.get('www.google.com', '/') # ===> Failure
186
187 assert_not_requested :get, "www.google.com" # ===> Success
188
189
190 ## Matching requests
191
192 An executed request matches stubbed request if it passes following criteria:
193
4306efa Ability to register and expect requests with empty body.
Bartosz Blimke authored
194 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
195 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
196 And request body is the same as stubbed request body or stubbed request body is not specified<br/>
197 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
198
199 ## Precedence of stubs
200
201 Always the last declared stub matching the request will be applied i.e:
202
203 stub_request(:get, "www.google.com").to_return(:body => "abc")
204 stub_request(:get, "www.google.com").to_return(:body => "def")
205
206 Net::HTTP.get('www.google.com', '/') # ====> "def"
207
208 ## Matching URIs
209
210 WebMock will match all different representations of the same URI.
211
212 I.e all the following representations of the URI are equal:
213
214 "www.google.com"
215 "www.google.com/"
216 "www.google.com:80"
217 "www.google.com:80/"
218 "http://www.google.com"
219 "http://www.google.com/"
220 "http://www.google.com:80"
221 "http://www.google.com:80/"
222
223 The following URIs with basic authentication are also equal for WebMock
224
225 "a b:pass@www.google.com"
226 "a b:pass@www.google.com/"
227 "a b:pass@www.google.com:80"
228 "a b:pass@www.google.com:80/"
229 "http://a b:pass@www.google.com"
230 "http://a b:pass@www.google.com/"
231 "http://a b:pass@www.google.com:80"
232 "http://a b:pass@www.google.com:80/"
233 "a%20b:pass@www.google.com"
234 "a%20b:pass@www.google.com/"
235 "a%20b:pass@www.google.com:80"
236 "a%20b:pass@www.google.com:80/"
237 "http://a%20b:pass@www.google.com"
238 "http://a%20b:pass@www.google.com/"
239 "http://a%20b:pass@www.google.com:80"
240 "http://a%20b:pass@www.google.com:80/"
241
242 or these
243
244 "www.google.com/big image.jpg/?a=big image&b=c"
245 "www.google.com/big%20image.jpg/?a=big%20image&b=c"
246 "www.google.com:80/big image.jpg/?a=big image&b=c"
247 "www.google.com:80/big%20image.jpg/?a=big%20image&b=c"
248 "http://www.google.com/big image.jpg/?a=big image&b=c"
249 "http://www.google.com/big%20image.jpg/?a=big%20image&b=c"
250 "http://www.google.com:80/big image.jpg/?a=big image&b=c"
251 "http://www.google.com:80/big%20image.jpg/?a=big%20image&b=c"
252
253
254 If you provide Regexp to match URI, WebMock will try to match it against every valid form of the same url.
255
256 I.e `/.*big image.*/` will match `www.google.com/big%20image.jpg` because it is equivalent of `www.google.com/big image.jpg`
257
258
259 ## Matching headers
260
261 WebMock will match request headers against stubbed request headers in the following situations:
262
263 1. Stubbed request has headers specified and request headers are the same as stubbed headers <br/>
264 i.e stubbed headers: `{ 'Header1' => 'Value1', 'Header1' => 'Value1' }`, requested: `{ 'Header1' => 'Value1', 'Header1' => 'Value1' }`
265
266 2. Stubbed request has headers specified and stubbed request headers are a subset of request headers <br/>
267 i.e stubbed headers: `{ 'Header1' => 'Value1' }`, requested: `{ 'Header1' => 'Value1', 'Header1' => 'Value1' }`
268
269 3. Stubbed request has no headers <br/>
270 i.e stubbed headers: `nil`, requested: `{ 'Header1' => 'Value1', 'Header1' => 'Value1' }`
271
272 WebMock normalises headers and treats all forms of same headers as equal:
273 i.e the following two sets of headers are equal:
274
275 `{ "Header1" => "value1", :content_length => 123, :X_CuStOm_hEAder => :value }`
276
277 `{ :header1 => "value1", "Content-Length" => 123, "x-cuSTOM-HeAder" => "value" }`
278
279
280 ## Bugs and Issues
281
282 Please submit them here [http://github.com/bblimke/webmock/issues](http://github.com/bblimke/webmock/issues)
283
284 ## Suggestions
285
286 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)
287
288 I'm particularly interested in how the DSL could be improved.
289
290 ## Credits
291
292 Thanks to my fellow [Bambinos](http://new-bamboo.co.uk/) for all the great suggestions!
293
294 Thank you Fakeweb! This library was inspired by [FakeWeb](fakeweb.rubyforge.org).
295 I took couple of solutions from that project. I also copied some code i.e Net:HTTP adapter.
296 Fakeweb architecture unfortunately didn't allow me to extend it easily with the features I needed.
297 I also preferred some things to work differently i.e request stub precedence.
298
299 ## Copyright
300
301 Copyright 2009 Bartosz Blimke. See LICENSE for details.
Something went wrong with that request. Please try again.