Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 291 lines (175 sloc) 9.47 kb
95e8298 Revert "WebMock module has to be included manually and is not include…
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 RSp…
Bartosz Blimke authored
36
37 require 'webmock'
38
39 include WebMock
95e8298 Revert "WebMock module has to be included manually and is not include…
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
91 ### Request with basic authentication
92
93 stub_request(:any, "john:smith@www.google.com")
94
95 Net::HTTP.get(URI.parse('http://john:smith@www.google.com')) # ===> Success
96
97 ### Matching uris using regular expressions
98
99 stub_request(:any, /.*google.*/)
100
101 Net::HTTP.get('www.google.com', '/') # ===> Success
102
103 ### Real requests to network can be allowed or disabled
104
105 WebMock.allow_net_connect!
106
107 stub_request(:any, "www.google.com").to_return(:body => "abc")
108
109 Net::HTTP.get('www.google.com', '/') # ===> "abc"
110
111 Net::HTTP.get('www.something.com', '/') # ===> /.+Something.+/
112
113 WebMock.disable_net_connect!
114
115 Net::HTTP.get('www.something.com', '/') # ===> Failure
116
117
118 ## Setting Expectations
119
120 ### Setting expectations in Test::Unit
121 require 'webmock/test_unit'
122
123 stub_request(:any, "www.google.com")
124
125 uri = URI.parse('http://www.google.com/')
126 req = Net::HTTP::Post.new(uri.path)
127 req['Content-Length'] = 3
128 res = Net::HTTP.start(uri.host, uri.port) {|http|
129 http.request(req, 'abc')
130 }
131
132 assert_requested :post, "http://www.google.com",
133 :headers => {'Content-Length' => 3}, :body => "abc", :times => 1 # ===> Success
134
135 assert_not_requested :get, "http://www.something.com" # ===> Success
136
137 ### Expecting real (not stubbed) requests
138
139 WebMock.allow_net_connect!
140
141 Net::HTTP.get('www.google.com', '/') # ===> Success
142
143 assert_requested :get, "http://www.google.com" # ===> Success
144
145
146 ### Setting expectations in RSpec
147 This style is borrowed from [fakeweb-matcher](http://github.com/freelancing-god/fakeweb-matcher)
148
149 require 'webmock/rspec'
150
151 WebMock.should have_requested(:get, "www.google.com").with(:body => "abc", :headers => {'Content-Length' => 3}).twice
152
153 WebMock.should_not have_requested(:get, "www.something.com")
154
155 ### Different way of setting expectations in RSpec
156
157 request(:post, "www.google.com").with(:body => "abc", :headers => {'Content-Length' => 3}).should have_been_made.once
158
159 request(:post, "www.something.com").should have_been_made.times(3)
160
161 request(:any, "www.example.com").should_not have_been_made
162
163
164 ## Clearing stubs and request history
165
166 If you want to reset all current stubs and history of requests use `WebMock.reset_webmock`
167
168 stub_request(:any, "www.google.com")
169
170 Net::HTTP.get('www.google.com', '/') # ===> Success
171
172 reset_webmock
173
174 Net::HTTP.get('www.google.com', '/') # ===> Failure
175
176 assert_not_requested :get, "www.google.com" # ===> Success
177
178
179 ## Matching requests
180
181 An executed request matches stubbed request if it passes following criteria:
182
4306efa Ability to register and expect requests with empty body.
Bartosz Blimke authored
183 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
184 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
185 And request body is the same as stubbed request body or stubbed request body is not specified<br/>
186 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 include…
Bartosz Blimke authored
187
188 ## Precedence of stubs
189
190 Always the last declared stub matching the request will be applied i.e:
191
192 stub_request(:get, "www.google.com").to_return(:body => "abc")
193 stub_request(:get, "www.google.com").to_return(:body => "def")
194
195 Net::HTTP.get('www.google.com', '/') # ====> "def"
196
197 ## Matching URIs
198
199 WebMock will match all different representations of the same URI.
200
201 I.e all the following representations of the URI are equal:
202
203 "www.google.com"
204 "www.google.com/"
205 "www.google.com:80"
206 "www.google.com:80/"
207 "http://www.google.com"
208 "http://www.google.com/"
209 "http://www.google.com:80"
210 "http://www.google.com:80/"
211
212 The following URIs with basic authentication are also equal for WebMock
213
214 "a b:pass@www.google.com"
215 "a b:pass@www.google.com/"
216 "a b:pass@www.google.com:80"
217 "a b:pass@www.google.com:80/"
218 "http://a b:pass@www.google.com"
219 "http://a b:pass@www.google.com/"
220 "http://a b:pass@www.google.com:80"
221 "http://a b:pass@www.google.com:80/"
222 "a%20b:pass@www.google.com"
223 "a%20b:pass@www.google.com/"
224 "a%20b:pass@www.google.com:80"
225 "a%20b:pass@www.google.com:80/"
226 "http://a%20b:pass@www.google.com"
227 "http://a%20b:pass@www.google.com/"
228 "http://a%20b:pass@www.google.com:80"
229 "http://a%20b:pass@www.google.com:80/"
230
231 or these
232
233 "www.google.com/big image.jpg/?a=big image&b=c"
234 "www.google.com/big%20image.jpg/?a=big%20image&b=c"
235 "www.google.com:80/big image.jpg/?a=big image&b=c"
236 "www.google.com:80/big%20image.jpg/?a=big%20image&b=c"
237 "http://www.google.com/big image.jpg/?a=big image&b=c"
238 "http://www.google.com/big%20image.jpg/?a=big%20image&b=c"
239 "http://www.google.com:80/big image.jpg/?a=big image&b=c"
240 "http://www.google.com:80/big%20image.jpg/?a=big%20image&b=c"
241
242
243 If you provide Regexp to match URI, WebMock will try to match it against every valid form of the same url.
244
245 I.e `/.*big image.*/` will match `www.google.com/big%20image.jpg` because it is equivalent of `www.google.com/big image.jpg`
246
247
248 ## Matching headers
249
250 WebMock will match request headers against stubbed request headers in the following situations:
251
252 1. Stubbed request has headers specified and request headers are the same as stubbed headers <br/>
253 i.e stubbed headers: `{ 'Header1' => 'Value1', 'Header1' => 'Value1' }`, requested: `{ 'Header1' => 'Value1', 'Header1' => 'Value1' }`
254
255 2. Stubbed request has headers specified and stubbed request headers are a subset of request headers <br/>
256 i.e stubbed headers: `{ 'Header1' => 'Value1' }`, requested: `{ 'Header1' => 'Value1', 'Header1' => 'Value1' }`
257
258 3. Stubbed request has no headers <br/>
259 i.e stubbed headers: `nil`, requested: `{ 'Header1' => 'Value1', 'Header1' => 'Value1' }`
260
261 WebMock normalises headers and treats all forms of same headers as equal:
262 i.e the following two sets of headers are equal:
263
264 `{ "Header1" => "value1", :content_length => 123, :X_CuStOm_hEAder => :value }`
265
266 `{ :header1 => "value1", "Content-Length" => 123, "x-cuSTOM-HeAder" => "value" }`
267
268
269 ## Bugs and Issues
270
271 Please submit them here [http://github.com/bblimke/webmock/issues](http://github.com/bblimke/webmock/issues)
272
273 ## Suggestions
274
275 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)
276
277 I'm particularly interested in how the DSL could be improved.
278
279 ## Credits
280
281 Thanks to my fellow [Bambinos](http://new-bamboo.co.uk/) for all the great suggestions!
282
283 Thank you Fakeweb! This library was inspired by [FakeWeb](fakeweb.rubyforge.org).
284 I took couple of solutions from that project. I also copied some code i.e Net:HTTP adapter.
285 Fakeweb architecture unfortunately didn't allow me to extend it easily with the features I needed.
286 I also preferred some things to work differently i.e request stub precedence.
287
288 ## Copyright
289
290 Copyright 2009 Bartosz Blimke. See LICENSE for details.
Something went wrong with that request. Please try again.