Permalink
Browse files

Added support for declaring timeout errors using `to_timeout`

  • Loading branch information...
1 parent 3314aad commit af52fe70ea96084a0a755c2549f54444968501c5 Bartosz Blimke committed Mar 14, 2010
View
16 README.md
@@ -127,7 +127,7 @@ You can also use WebMock without RSpec or Test::Unit support:
req = Net::HTTP::Get.new("/")
Net::HTTP.start("www.example.com") { |http| http.request(req) }.message # ===> "Internal Server Error"
-
+
### Replaying raw responses recorded with `curl -is`
`curl -is www.example.com > /tmp/example_curl_-is_output.txt`
@@ -162,6 +162,18 @@ You can also use WebMock without RSpec or Test::Unit support:
RestClient.post('www.example.net', 'abc') # ===> "abc\n"
+### Raising errors
+
+ stub_request(:any, 'www.example.net').to_raise(StandardError)
+
+ RestClient.post('www.example.net', 'abc') # ===> StandardError
+
+### Raising timeout errors
+
+ stub_request(:any, 'www.example.net').to_timeout
+
+ RestClient.post('www.example.net', 'abc') # ===> RestClient::RequestTimeout
+
### Multiple responses for repeated requests
stub_request(:get, "www.example.com").to_return({:body => "abc"}, {:body => "def"})
@@ -172,7 +184,7 @@ You can also use WebMock without RSpec or Test::Unit support:
Net::HTTP.get('www.example.com', '/') # ===> "def\n"
-### Multiple responses using chained `to_return()` or `to_raise()` declarations
+### Multiple responses using chained `to_return()`, `to_raise()` or `to_timeout` declarations
stub_request(:get, "www.example.com").
to_return({:body => "abc"}).then. #then() is just a syntactic sugar
View
1 lib/webmock/http_lib_adapters/httpclient.rb
@@ -59,6 +59,7 @@ def build_httpclient_response(webmock_response, stream = false, &block)
response.reason=webmock_response.status[1]
webmock_response.headers.to_a.each { |name, value| response.header.set(name, value) }
+ raise HTTPClient::TimeoutError if webmock_response.should_timeout
webmock_response.raise_error_if_any
block.call(nil, body) if block
View
2 lib/webmock/http_lib_adapters/net_http.rb
@@ -122,6 +122,8 @@ def build_net_http_response(webmock_response, &block)
response.extend StubResponse
+ raise Timeout::Error if webmock_response.should_timeout
+
webmock_response.raise_error_if_any
yield response if block_given?
View
1 lib/webmock/http_lib_adapters/patron.rb
@@ -66,6 +66,7 @@ def build_request_signature(req)
end
def build_patron_response(webmock_response)
+ raise Patron::TimeoutError if webmock_response.should_timeout
webmock_response.raise_error_if_any
res = Patron::Response.new
res.instance_variable_set(:@body, webmock_response.body)
View
5 lib/webmock/request_stub.rb
@@ -29,6 +29,11 @@ def to_raise(*exceptions)
})
self
end
+
+ def to_timeout
+ @responses_sequences << ResponsesSequence.new([ResponseFactory.response_for(:should_timeout => true)])
+ self
+ end
def response
if @responses_sequences.empty?
View
10 lib/webmock/response.rb
@@ -60,25 +60,33 @@ def raise_error_if_any
raise @exception.new('Exception from WebMock') if @exception
end
+ def should_timeout
+ @should_timeout == true
+ end
+
def options=(options)
self.headers = options[:headers]
self.status = options[:status]
self.body = options[:body]
@exception = options[:exception]
+ @should_timeout = options[:should_timeout]
end
def evaluate!(request_signature)
self.body = @body.call(request_signature) if @body.is_a?(Proc)
self.headers = @headers.call(request_signature) if @headers.is_a?(Proc)
self.status = @status.call(request_signature) if @status.is_a?(Proc)
+ @should_timeout = @should_timeout.call(request_signature) if @should_timeout.is_a?(Proc)
+ @exception = @exception.call(request_signature) if @exception.is_a?(Proc)
self
end
def ==(other)
self.body == other.body &&
self.headers === other.headers &&
self.status == other.status &&
- self.exception == other.exception
+ self.exception == other.exception &&
+ self.should_timeout == other.should_timeout
end
private
View
4 spec/httpclient_spec_helper.rb
@@ -25,6 +25,10 @@ def http_request(method, uri, options = {}, &block)
})
end
+ def client_timeout_exception_class
+ HTTPClient::TimeoutError
+ end
+
def default_client_request_headers(request_method = nil, has_body = false)
{'Content-Type'=>'application/x-www-form-urlencoded'} if request_method == 'POST' && has_body
end
View
4 spec/net_http_spec_helper.rb
@@ -32,6 +32,10 @@ def default_client_request_headers(request_method = nil, has_body = false)
[k, v.flatten]
}.flatten]
end
+
+ def client_timeout_exception_class
+ Timeout::Error
+ end
# Sets several expectations that a real HTTP request makes it
# past WebMock to the socket layer. You can use this when you need to check
View
16 spec/patron_spec_helper.rb
@@ -3,30 +3,34 @@ def http_request(method, uri, options = {}, &block)
uri = Addressable::URI.heuristic_parse(uri)
sess = Patron::Session.new
sess.base_url = "#{uri.omit(:userinfo, :query).normalize.to_s}".gsub(/\/$/,"")
-
+
sess.username = uri.user
sess.password = uri.password
-
+
sess.timeout = 10
-
+
response = sess.request(method, "#{uri.path}#{uri.query ? '?' : ''}#{uri.query}", options[:headers] || {}, {
:data => options[:body]
})
-
+
OpenStruct.new({
:body => response.body,
:headers => WebMock::Util::Headers.normalize_headers(response.headers),
:status => response.status.to_s,
:message => response.status_line
})
end
-
+
def default_client_request_headers(request_method = nil, has_body = false)
nil
end
+ def client_timeout_exception_class
+ Patron::TimeoutError
+ end
+
def setup_expectations_for_real_request(options = {})
#TODO
- end
+ end
end
View
22 spec/request_stub_spec.rb
@@ -124,6 +124,28 @@
end
+ describe "to_timeout" do
+
+ it "should assign response with timeout" do
+ @request_stub.to_timeout
+ @request_stub.response.should_timeout.should be_true
+ end
+
+ it "should assign sequence of responses with response with timeout" do
+ @request_stub.to_return(:body => "abc").then.to_timeout
+ @request_stub.response.body.should == "abc"
+ @request_stub.response.should_timeout.should be_true
+ end
+
+ it "should allow multiple timeouts to be declared" do
+ @request_stub.to_timeout.then.to_timeout.then.to_return(:body => "abc")
+ @request_stub.response.should_timeout.should be_true
+ @request_stub.response.should_timeout.should be_true
+ @request_stub.response.body.should == "abc"
+ end
+
+ end
+
describe "times" do
View
14 spec/response_spec.rb
@@ -64,6 +64,20 @@
end
end
+
+ describe "timeout" do
+
+ it "should know if it should timeout" do
+ @response = Response.new(:should_timeout => true)
+ @response.should_timeout.should be_true
+ end
+
+ it "should not timeout by default" do
+ @response = Response.new
+ @response.should_timeout.should be_false
+ end
+
+ end
describe "body" do
View
19 spec/webmock_spec.rb
@@ -291,6 +291,25 @@ class MyException < StandardError; end;
end
+ describe "raising timeout errors" do
+
+ it "should raise timeout exception if declared in a stubbed response" do
+ stub_http_request(:get, "www.example.com").to_timeout
+ lambda {
+ http_request(:get, "http://www.example.com/")
+ }.should raise_error(client_timeout_exception_class)
+ end
+
+ it "should raise exception if declared in a stubbed response after returning declared response" do
+ stub_http_request(:get, "www.example.com").to_return(:body => "abc").then.to_timeout
+ http_request(:get, "http://www.example.com/").body.should == "abc"
+ lambda {
+ http_request(:get, "http://www.example.com/")
+ }.should raise_error(client_timeout_exception_class)
+ end
+
+ end
+
describe "returning stubbed responses" do
it "should return declared body" do

0 comments on commit af52fe7

Please sign in to comment.