webmock 0.7.1 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +9 -0
- data/README.md +169 -76
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/lib/webmock.rb +12 -9
- data/lib/webmock/adapters/rspec.rb +20 -22
- data/lib/webmock/adapters/rspec/matchers.rb +4 -4
- data/lib/webmock/adapters/rspec/webmock_matcher.rb +2 -2
- data/lib/webmock/adapters/test_unit.rb +20 -21
- data/lib/webmock/http_lib_adapters/net_http.rb +51 -15
- data/lib/webmock/request_profile.rb +5 -44
- data/lib/webmock/request_registry.rb +10 -11
- data/lib/webmock/request_signature.rb +44 -0
- data/lib/webmock/request_stub.rb +3 -3
- data/lib/webmock/response.rb +1 -1
- data/lib/webmock/rspec.rb +1 -0
- data/lib/webmock/test_unit.rb +1 -0
- data/lib/webmock/util/hash_counter.rb +16 -8
- data/lib/webmock/util/headers.rb +23 -0
- data/lib/webmock/util/uri.rb +81 -0
- data/lib/webmock/webmock.rb +16 -19
- data/spec/net_http_spec.rb +10 -9
- data/spec/other_net_http_libs_spec.rb +3 -1
- data/spec/request_profile_spec.rb +6 -116
- data/spec/request_registry_spec.rb +12 -17
- data/spec/request_signature_spec.rb +155 -0
- data/spec/request_stub_spec.rb +2 -2
- data/spec/response_spec.rb +1 -1
- data/spec/spec_helper.rb +4 -1
- data/spec/util/hash_counter_spec.rb +4 -4
- data/spec/util/headers_spec.rb +11 -0
- data/spec/util/uri_spec.rb +213 -0
- data/spec/vendor/addressable/lib/addressable/uri.rb +8 -0
- data/spec/vendor/addressable/lib/uri.rb +0 -0
- data/spec/webmock_spec.rb +58 -10
- data/test/test_helper.rb +5 -1
- data/test/test_webmock.rb +11 -6
- data/webmock.gemspec +21 -6
- metadata +28 -6
- data/lib/webmock/url.rb +0 -46
- data/lib/webmock/utility.rb +0 -65
- data/spec/utility_spec.rb +0 -70
data/CHANGELOG
ADDED
data/README.md
CHANGED
@@ -1,82 +1,100 @@
|
|
1
1
|
WebMock
|
2
2
|
=======
|
3
3
|
|
4
|
-
Library for stubbing HTTP requests in Ruby.
|
4
|
+
Library for stubbing HTTP requests and setting expectations on HTTP requests in Ruby.
|
5
5
|
|
6
6
|
Features
|
7
7
|
--------
|
8
8
|
|
9
|
-
* Stubbing requests
|
10
|
-
*
|
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.
|
11
14
|
* Support for Test::Unit and RSpec (and can be easily extended to other frameworks)
|
12
|
-
* Support for Net::
|
13
|
-
*
|
14
|
-
|
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
|
15
17
|
|
16
18
|
Installation
|
17
19
|
------------
|
18
20
|
|
19
21
|
gem install webmock --source http://gemcutter.org
|
20
22
|
|
21
|
-
In your `test/test_helper.rb`
|
23
|
+
In your `test/test_helper.rb` add these two lines:
|
22
24
|
|
23
|
-
require 'webmock'
|
25
|
+
require 'webmock/test_unit'
|
24
26
|
|
25
27
|
include WebMock
|
26
28
|
|
27
|
-
|
29
|
+
or if you use RSpec add these lines to `spec/spec_helper`:
|
30
|
+
|
31
|
+
require 'webmock/rspec'
|
32
|
+
|
33
|
+
include WebMock
|
34
|
+
|
35
|
+
You can also use WebMock without RSpec or Test::Unit support:
|
36
|
+
|
37
|
+
require 'webmock'
|
38
|
+
|
39
|
+
include WebMock
|
28
40
|
|
29
41
|
## Examples
|
30
42
|
|
31
|
-
|
43
|
+
|
44
|
+
|
45
|
+
## Stubbing
|
46
|
+
|
47
|
+
|
48
|
+
### Stubbed request based on uri only and with the default response
|
32
49
|
|
33
50
|
stub_request(:any, "www.google.com")
|
34
51
|
|
35
|
-
Net::HTTP.get(
|
36
|
-
|
37
|
-
### Stubbing requests based on method,
|
52
|
+
Net::HTTP.get("www.google.com", "/") # ===> Success
|
53
|
+
|
54
|
+
### Stubbing requests based on method, uri, body and headers
|
38
55
|
|
39
56
|
stub_request(:post, "www.google.com").with(:body => "abc", :headers => { 'Content-Length' => 3 })
|
40
57
|
|
41
|
-
|
42
|
-
req = Net::HTTP::Post.new(
|
58
|
+
uri = URI.parse("http://www.google.com/")
|
59
|
+
req = Net::HTTP::Post.new(uri.path)
|
43
60
|
req['Content-Length'] = 3
|
44
|
-
res = Net::HTTP.start(
|
45
|
-
http.request(req,
|
61
|
+
res = Net::HTTP.start(uri.host, uri.port) {|http|
|
62
|
+
http.request(req, "abc")
|
46
63
|
} # ===> Success
|
47
64
|
|
48
65
|
### Matching custom request headers
|
49
66
|
|
50
|
-
stub_request(:any, "www.google.com").
|
67
|
+
stub_request(:any, "www.google.com").
|
68
|
+
with( :headers=>{ 'Header-Name' => 'Header-Value' } ).to_return(:body => "abc", :status => 200)
|
51
69
|
|
52
|
-
|
53
|
-
req = Net::HTTP::Post.new(
|
54
|
-
req['Header-Name'] =
|
55
|
-
res = Net::HTTP.start(
|
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|
|
56
74
|
http.request(req, 'abc')
|
57
75
|
} # ===> Success
|
58
76
|
|
59
|
-
###
|
77
|
+
### Stubbing with custom response
|
60
78
|
|
61
|
-
stub_request(:any, "www.google.com").to_return(:body => "abc", :status => 200, :headers => { 'Content-Length' => 3 })
|
79
|
+
stub_request(:any, "www.google.com").to_return(:body => "abc", :status => 200, :headers => { 'Content-Length' => 3 } )
|
62
80
|
|
63
|
-
Net::HTTP.get(
|
64
|
-
|
65
|
-
### Custom response with body as
|
81
|
+
Net::HTTP.get("www.google.com", '/') # ===> "abc"
|
82
|
+
|
83
|
+
### Custom response with body specified as a path to file
|
66
84
|
|
67
85
|
File.open('/tmp/response_body.txt', 'w') { |f| f.puts 'abc' }
|
68
86
|
|
69
87
|
stub_request(:any, "www.google.com").to_return(:body => "/tmp/response_body.txt", :status => 200)
|
70
88
|
|
71
89
|
Net::HTTP.get('www.google.com', '/') # ===> "abc\n"
|
72
|
-
|
90
|
+
|
73
91
|
### Request with basic authentication
|
74
92
|
|
75
93
|
stub_request(:any, "john:smith@www.google.com")
|
76
94
|
|
77
95
|
Net::HTTP.get(URI.parse('http://john:smith@www.google.com')) # ===> Success
|
78
|
-
|
79
|
-
### Matching
|
96
|
+
|
97
|
+
### Matching uris using regular expressions
|
80
98
|
|
81
99
|
stub_request(:any, /.*google.*/)
|
82
100
|
|
@@ -96,29 +114,23 @@ Now you are ready to write your tests/specs with stubbed HTTP calls.
|
|
96
114
|
|
97
115
|
Net::HTTP.get('www.something.com', '/') # ===> Failure
|
98
116
|
|
99
|
-
### Clearing stubs
|
100
|
-
|
101
|
-
stub_request(:any, "www.google.com")
|
102
|
-
|
103
|
-
Net::HTTP.get('www.google.com', '/') # ===> Success
|
104
|
-
|
105
|
-
reset_webmock
|
106
|
-
|
107
|
-
Net::HTTP.get('www.google.com', '/') # ===> Failure
|
108
117
|
|
118
|
+
## Setting Expectations
|
109
119
|
|
110
|
-
###
|
120
|
+
### Setting expectations in Test::Unit
|
121
|
+
require 'webmock/test_unit'
|
111
122
|
|
112
123
|
stub_request(:any, "www.google.com")
|
113
124
|
|
114
|
-
|
115
|
-
req = Net::HTTP::Post.new(
|
125
|
+
uri = URI.parse('http://www.google.com/')
|
126
|
+
req = Net::HTTP::Post.new(uri.path)
|
116
127
|
req['Content-Length'] = 3
|
117
|
-
res = Net::HTTP.start(
|
128
|
+
res = Net::HTTP.start(uri.host, uri.port) {|http|
|
118
129
|
http.request(req, 'abc')
|
119
130
|
}
|
120
131
|
|
121
|
-
assert_requested :post, "http://www.google.com",
|
132
|
+
assert_requested :post, "http://www.google.com",
|
133
|
+
:headers => {'Content-Length' => 3}, :body => "abc", :times => 1 # ===> Success
|
122
134
|
|
123
135
|
assert_not_requested :get, "http://www.something.com" # ===> Success
|
124
136
|
|
@@ -130,68 +142,149 @@ Now you are ready to write your tests/specs with stubbed HTTP calls.
|
|
130
142
|
|
131
143
|
assert_requested :get, "http://www.google.com" # ===> Success
|
132
144
|
|
133
|
-
### RSpec matchers 1
|
134
145
|
|
135
|
-
|
136
|
-
|
137
|
-
request(:post, "www.something.com").should have_been_made.times(3)
|
138
|
-
|
139
|
-
request(:any, "www.example.com").should_not have_been_made
|
146
|
+
### Setting expectations in RSpec
|
147
|
+
This style is borrowed from [fakeweb-matcher](http://github.com/freelancing-god/fakeweb-matcher)
|
140
148
|
|
141
|
-
|
149
|
+
require 'webmock/rspec'
|
142
150
|
|
143
151
|
WebMock.should have_requested(:get, "www.google.com").with(:body => "abc", :headers => {'Content-Length' => 3}).twice
|
144
152
|
|
145
153
|
WebMock.should_not have_requested(:get, "www.something.com")
|
146
154
|
|
147
|
-
|
148
|
-
-----
|
155
|
+
### Different way of setting expectations in RSpec
|
149
156
|
|
150
|
-
|
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)
|
151
160
|
|
152
|
-
|
161
|
+
request(:any, "www.example.com").should_not have_been_made
|
153
162
|
|
154
|
-
* request url matches stubbed request url pattern
|
155
|
-
* and request method is the same as stubbed request method or stubbed request method is :any
|
156
|
-
* and request body is the same as stubbed request body or stubbed request body is not set (is nil)
|
157
|
-
* and request headers are the same as stubbed request headers or stubbed request headers are a subset of request headers or stubbed request headers are not set
|
158
163
|
|
159
|
-
|
164
|
+
## Clearing stubs and request history
|
160
165
|
|
161
|
-
|
162
|
-
|
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
|
+
|
183
|
+
Request URI matches stubbed request URI string or Regexp pattern<br/>
|
184
|
+
And request method is the same as stubbed request method or stubbed request method is :any<br/>
|
185
|
+
And request body is the same as stubbed request body or stubbed request body is not set (is nil)<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 set
|
187
|
+
|
188
|
+
## Precedence of stubs
|
189
|
+
|
190
|
+
Always the last declared stub matching the request will be applied i.e:
|
163
191
|
|
164
192
|
stub_request(:get, "www.google.com").to_return(:body => "abc")
|
165
193
|
stub_request(:get, "www.google.com").to_return(:body => "def")
|
166
194
|
|
167
195
|
Net::HTTP.get('www.google.com', '/') # ====> "def"
|
168
196
|
|
169
|
-
|
170
|
-
|
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
|
171
270
|
|
172
271
|
Please submit them here [http://github.com/bblimke/webmock/issues](http://github.com/bblimke/webmock/issues)
|
173
272
|
|
174
|
-
Suggestions
|
175
|
-
------------
|
273
|
+
## Suggestions
|
176
274
|
|
177
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)
|
178
276
|
|
179
277
|
I'm particularly interested in how the DSL could be improved.
|
180
278
|
|
181
|
-
|
182
|
-
----
|
183
|
-
|
184
|
-
* Add EventMachine::Protocols::HttpClient adapter
|
279
|
+
## Credits
|
185
280
|
|
186
|
-
|
187
|
-
-------
|
281
|
+
Thanks to my fellow [Bambinos](http://new-bamboo.co.uk/) for all the great suggestions!
|
188
282
|
|
189
|
-
Thank you Fakeweb! This library
|
190
|
-
I took couple of solutions from that project. I also copied some code i.e Net:
|
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.
|
191
285
|
Fakeweb architecture unfortunately didn't allow me to extend it easily with the features I needed.
|
192
286
|
I also preferred some things to work differently i.e request stub precedence.
|
193
287
|
|
194
|
-
Copyright
|
195
|
-
---------
|
288
|
+
## Copyright
|
196
289
|
|
197
290
|
Copyright 2009 Bartosz Blimke. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -10,6 +10,7 @@ begin
|
|
10
10
|
gem.email = "bartosz.blimke@gmail.com"
|
11
11
|
gem.homepage = "http://github.com/bblimke/webmock"
|
12
12
|
gem.authors = ["Bartosz Blimke"]
|
13
|
+
gem.add_dependency "addressable", ">= 2.1.1"
|
13
14
|
gem.add_development_dependency "rspec", ">= 1.2.9"
|
14
15
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
16
|
end
|
@@ -34,7 +35,7 @@ require 'rake/testtask'
|
|
34
35
|
Rake::TestTask.new(:test) do |test|
|
35
36
|
test.test_files = FileList["test/**/*.rb"].exclude("test/test_helper.rb")
|
36
37
|
test.verbose = false
|
37
|
-
test.warning =
|
38
|
+
test.warning = false
|
38
39
|
end
|
39
40
|
|
40
41
|
task :spec => :check_dependencies
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.2
|
data/lib/webmock.rb
CHANGED
@@ -1,18 +1,21 @@
|
|
1
1
|
require 'singleton'
|
2
2
|
|
3
|
+
require 'addressable/uri'
|
4
|
+
|
3
5
|
require 'webmock/http_lib_adapters/net_http'
|
4
6
|
|
5
7
|
require 'webmock/errors'
|
8
|
+
|
9
|
+
require 'webmock/util/uri'
|
10
|
+
require 'webmock/util/headers'
|
11
|
+
require 'webmock/util/hash_counter'
|
12
|
+
|
6
13
|
require 'webmock/request_profile'
|
7
|
-
require 'webmock/
|
8
|
-
require 'webmock/url'
|
14
|
+
require 'webmock/request_signature'
|
9
15
|
require 'webmock/request_stub'
|
10
|
-
require 'webmock/utility'
|
11
|
-
require 'webmock/config'
|
12
16
|
require 'webmock/response'
|
13
|
-
require 'webmock/util/hash_counter'
|
14
|
-
require 'webmock/request_registry'
|
15
|
-
require 'webmock/webmock'
|
16
17
|
|
17
|
-
require 'webmock/
|
18
|
-
require 'webmock/
|
18
|
+
require 'webmock/request_execution_verifier'
|
19
|
+
require 'webmock/config'
|
20
|
+
require 'webmock/request_registry'
|
21
|
+
require 'webmock/webmock'
|
@@ -1,23 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
14
|
-
}
|
15
|
-
|
16
|
-
module WebMock
|
17
|
-
private
|
18
|
-
def assertion_failure(message)
|
19
|
-
raise Spec::Expectations::ExpectationNotMetError.new(message)
|
20
|
-
end
|
1
|
+
require 'webmock'
|
2
|
+
require 'spec'
|
3
|
+
require 'webmock/adapters/rspec/request_profile_matcher'
|
4
|
+
require 'webmock/adapters/rspec/webmock_matcher'
|
5
|
+
require 'webmock/adapters/rspec/matchers'
|
6
|
+
|
7
|
+
Spec::Runner.configure { |config|
|
8
|
+
|
9
|
+
config.include WebMock::Matchers
|
10
|
+
|
11
|
+
config.before :each do
|
12
|
+
WebMock.reset_webmock
|
21
13
|
end
|
22
|
-
|
23
|
-
|
14
|
+
}
|
15
|
+
|
16
|
+
module WebMock
|
17
|
+
private
|
18
|
+
def assertion_failure(message)
|
19
|
+
raise Spec::Expectations::ExpectationNotMetError.new(message)
|
20
|
+
end
|
21
|
+
end
|