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.
See actionpack-2.3.14/lib/action_controller/integration.rb:342
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
Thanks for this tip! Saved me a bunch of trouble tonight while trying to teach an old app some new tricks.