Integration tests call the whole rack middleware stack, but stubbornly return the last controller response, which can be completely different especially if you use warden or other middleware-tools.
To fix that and prepare for Rails 3 (which also relies on rack response) do this:
# test/test_helper.rb if Rails::VERSION::MAJOR == 2 # https://grosser.it/2012/10/19/rails-2-your-integration-tests-are-lying/ # make integration tests use rack response, so we can test our middlewares # and not only the pure controller response ActionController::Base.class_eval do # this is usually done just-in-time by #process but we need to do it earlier include ActionController::Integration::ControllerCapture # then we hide last_instantiation from #process def self.last_instantiation;end end ActionController::Integration::Session.class_eval do def process_with_rackify(*args) process_without_rackify(*args) ensure # needed e.g. inside of assert_redirect_to capture = ActionController::Integration::ControllerCapture::ClassMethods # not set by original #process @response.redirected_to = @response.headers["Location"] if @response if @controller = capture.send(:class_variable_get, :@@last_instantiation) @request = @controller.request @response.template = @controller.response.template if @controller.response @controller.send(:set_test_assigns) end end alias_method_chain :process, :rackify end end
One thought on “Rails 2: Your integration tests are lying”
Thanks for this tip! Saved me a bunch of trouble tonight while trying to teach an old app some new tricks.