From 028a236f102cb617d1c3e39d3de9d51b99c4fd61 Mon Sep 17 00:00:00 2001 From: Alex Wayne Date: Wed, 21 May 2008 08:10:47 -0700 Subject: Added documentation for ActiveResource::HttpMock. Special thanks to Clever Title Pending: http://seangeo.blogspot.com/2007/09/testing-activeresource.html --- activeresource/lib/active_resource/http_mock.rb | 89 ++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 9 deletions(-) diff --git a/activeresource/lib/active_resource/http_mock.rb b/activeresource/lib/active_resource/http_mock.rb index d1c1412575..82e3bc8370 100644 --- a/activeresource/lib/active_resource/http_mock.rb +++ b/activeresource/lib/active_resource/http_mock.rb @@ -2,9 +2,53 @@ require 'active_resource/connection' module ActiveResource class InvalidRequestError < StandardError; end #:nodoc: - + + # One thing that has always been a pain with remote web services is testing. The HttpMock + # class makes it easy to test your Active Resource models by creating a set of mock responses to specific + # requests. + # + # To test your Active Resource model, you simply call the ActiveResource::HttpMock.respond_to + # method with an attached block. The block declares a set of URIs with expected input, and the output + # each request should return. The passed in block has any number of entries in the following generalized + # format: + # + # mock.http_method(path, request_headers = {}, body = nil, status = 200, response_headers = {}) + # + # * http_method - The HTTP method to listen for. This can be +get+, +post+, +put+, +delete+ or + # +head+. + # * path - A string, starting with a "/", defining the URI that is expected to be + # called. + # * request_headers - Headers that are expected along with the request. This argument uses a + # hash format, such as { "Content-Type" => "application/xml" }. This mock will only trigger + # if your tests sends a request with identical headers. + # * body - The data to be returned. This should be a string of ActiveResource parseable content, + # such as XML. + # * status - The HTTP response code, as an integer, to return with the response. + # * response_headers - Headers to be returned with the response. Uses the same hash format as + # request_headers listed above. + # + # In order for a mock to deliver its content, the incoming request must match by the http_method, + # +path+ and request_headers. If no match is found an InvalidRequestError exception + # will be raised letting you know you need to create a new mock for that request. + # + # ==== Example + # def setup + # @matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person") + # ActiveResource::HttpMock.respond_to do |mock| + # mock.post "/people.xml", {}, @matz, 201, "Location" => "/people/1.xml" + # mock.get "/people/1.xml", {}, @matz + # mock.put "/people/1.xml", {}, nil, 204 + # mock.delete "/people/1.xml", {}, nil, 200 + # end + # end + # + # def test_get_matz + # person = Person.find(1) + # assert_equal "Matz", person.name + # end + # class HttpMock - class Responder + class Responder #:nodoc: def initialize(responses) @responses = responses end @@ -19,15 +63,41 @@ module ActiveResource end class << self + + # Returns an array of all request objects that have been sent to the mock. You can use this to check + # wether or not your model actually sent an HTTP request. + # + # ==== Example + # def setup + # @matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person") + # ActiveResource::HttpMock.respond_to do |mock| + # mock.get "/people/1.xml", {}, @matz + # end + # end + # + # def test_should_request_remote_service + # person = Person.find(1) # Call the remote service + # + # # This request object has the same HTTP method and path as declared by the mock + # expected_request = ActiveResource::Request.new(:get, "/people/1.xml") + # + # # Assert that the mock received, and responded to, the expected request from the model + # assert ActiveResource::HttpMock.requests.include?(expected_request) + # end def requests @@requests ||= [] end - + + # Returns a hash of request => response pairs for all all responses this mock has delivered, where +request+ + # is an instance of ActiveResource::Request and the response is, naturally, an instance of + # ActiveResource::Response. def responses @@responses ||= {} end - - def respond_to(pairs = {}) + + # Accepts a block which declares a set of requests and responses for the HttpMock to respond to. See the main + # ActiveResource::HttpMock description for a more detailed explanation. + def respond_to(pairs = {}) #:yields: mock reset! pairs.each do |(path, response)| responses[path] = response @@ -39,7 +109,8 @@ module ActiveResource Responder.new(responses) end end - + + # Deletes all logged requests and responses. def reset! requests.clear responses.clear @@ -65,8 +136,8 @@ module ActiveResource end EOE end - - def initialize(site) + + def initialize(site) #:nodoc: @site = site end end @@ -135,7 +206,7 @@ module ActiveResource end end - class Connection + class Connection private silence_warnings do def http -- cgit v1.2.3