HttpMock is great to test the client side of a REST API. But if you’re responsible for client and server side of the API, it makes sense to do full end-to-end tests from your application’s controllers to the client app. Up to now, you’d need to set up a local server to end-to-end-test the ActiveResource requests from the client app against.
Instead, I’d like to just use Rails’ integration test infrastructure. All ActiveResource requests can be directly routed to the app’s controller, just as known from integration tests. This is how tests could then look like:
require 'active_resource_integration_test_support' class APIIntegrationTest < ActionController::IntegrationTest test "API requests work end-to-end" do ActiveResource::Connection.with_integration_test_session(open_session) do result = APIClient.some_method_that_requires_api_access assert result end end end |
All you need to get there, is drop this monkey patch into your app’s lib directory and require it from the ActiveResource integration tests.
module ActiveResource class Connection # ActiveResource requests will use the supplied # ActionController::Integration::Session to execute its request in the # given block. # def self.with_integration_test_session (session) previous_session = Connection.integration_test_session begin Connection.integration_test_session = session yield ensure Connection.integration_test_session = previous_session end end private mattr_accessor :integration_test_session def request_with_integration_test_support (method, path, *arguments) if self.class.integration_test_session # arguments are data, header for post, put; else header header = arguments.last data = arguments.length > 1 ? arguments.first : nil Rails.logger.debug("#{method.to_s.upcase} #{path}") self.class.integration_test_session.send(method, path, data, header) #Rails.logger.debug(self.class.integration_test_session.response.body) handle_response(self.class.integration_test_session.response) self.class.integration_test_session.response else Rails.logger.debug("No session set, using default ActiveResource requests") request_without_integration_test_support(method, path, *arguments) end end alias_method_chain :request, :integration_test_support end end |
If you find this useful, have a look at the pending Rails patch at Lighthouse to support getting this into Rails.