0
@@ -2,9 +2,53 @@ require 'active_resource/connection'
0
class InvalidRequestError < StandardError; end #:nodoc:
0
+ # One thing that has always been a pain with remote web services is testing. The <tt>HttpMock</tt>
0
+ # class makes it easy to test your Active Resource models by creating a set of mock responses to specific
0
+ # To test your Active Resource model, you simply call the <tt>ActiveResource::HttpMock.respond_to</tt>
0
+ # method with an attached block. The block declares a set of URIs with expected input, and the output
0
+ # each request should return. The passed in block has any number of entries in the following generalized
0
+ # mock.http_method(path, request_headers = {}, body = nil, status = 200, response_headers = {})
0
+ # * <tt>http_method</tt> - The HTTP method to listen for. This can be +get+, +post+, +put+, +delete+ or
0
+ # * <tt>path</tt> - A string, starting with a <tt>"/"</tt>, defining the URI that is expected to be
0
+ # * <tt>request_headers</tt> - Headers that are expected along with the request. This argument uses a
0
+ # hash format, such as <tt>{ "Content-Type" => "application/xml" }</tt>. This mock will only trigger
0
+ # if your tests sends a request with identical headers.
0
+ # * <tt>body</tt> - The data to be returned. This should be a string of ActiveResource parseable content,
0
+ # * <tt>status</tt> - The HTTP response code, as an integer, to return with the response.
0
+ # * <tt>response_headers</tt> - Headers to be returned with the response. Uses the same hash format as
0
+ # <tt>request_headers</tt> listed above.
0
+ # In order for a mock to deliver its content, the incoming request must match by the <tt>http_method</tt>,
0
+ # +path+ and <tt>request_headers</tt>. If no match is found an <tt>InvalidRequestError</tt> exception
0
+ # will be raised letting you know you need to create a new mock for that request.
0
+ # @matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person")
0
+ # ActiveResource::HttpMock.respond_to do |mock|
0
+ # mock.post "/people.xml", {}, @matz, 201, "Location" => "/people/1.xml"
0
+ # mock.get "/people/1.xml", {}, @matz
0
+ # mock.put "/people/1.xml", {}, nil, 204
0
+ # mock.delete "/people/1.xml", {}, nil, 200
0
+ # person = Person.find(1)
0
+ # assert_equal "Matz", person.name
0
+ class Responder
#:nodoc:0
def initialize(responses)
0
@@ -19,15 +63,41 @@ module ActiveResource
0
+ # Returns an array of all request objects that have been sent to the mock. You can use this to check
0
+ # wether or not your model actually sent an HTTP request.
0
+ # @matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person")
0
+ # ActiveResource::HttpMock.respond_to do |mock|
0
+ # mock.get "/people/1.xml", {}, @matz
0
+ # def test_should_request_remote_service
0
+ # person = Person.find(1) # Call the remote service
0
+ # # This request object has the same HTTP method and path as declared by the mock
0
+ # expected_request = ActiveResource::Request.new(:get, "/people/1.xml")
0
+ # # Assert that the mock received, and responded to, the expected request from the model
0
+ # assert ActiveResource::HttpMock.requests.include?(expected_request)
0
+ # Returns a hash of <tt>request => response</tt> pairs for all all responses this mock has delivered, where +request+
0
+ # is an instance of <tt>ActiveResource::Request</tt> and the response is, naturally, an instance of
0
+ # <tt>ActiveResource::Response</tt>.
0
- def respond_to(pairs = {})
0
+ # Accepts a block which declares a set of requests and responses for the HttpMock to respond to. See the main
0
+ # <tt>ActiveResource::HttpMock</tt> description for a more detailed explanation.
0
+ def respond_to(pairs = {}) #:yields: mock
0
pairs.each do |(path, response)|
0
responses[path] = response
0
@@ -39,7 +109,8 @@ module ActiveResource
0
Responder.new(responses)
0
+ # Deletes all logged requests and responses.
0
@@ -65,8 +136,8 @@ module ActiveResource
0
+ def initialize(site) #:nodoc:
0
@@ -135,7 +206,7 @@ module ActiveResource