rails: Just started (3 days ago) getting ActionDispatch::IllegalStateError for controllers rspec test with edge rails

Just started (3 days ago) getting ActionDispatch::IllegalStateError for controllers rspec test with edge rails.

Steps to reproduce

  • Given you have a repo: https://github.com/jasnow/testing-app5edge And you run the following: rspec ./spec/controllers/posts_controller_spec.rb:17 Then it will run without errors.
  • Now run “bundle upgrade” and you see the following gems were upgraded:
    ...Rails
    -  revision: c4cb6862babd2665a65056e205c2a5fd17a5d99d
    +  revision: 66ebbc4952f6cfb37d719f63036441ef98149418
    ...
    -    rails-dom-testing (2.0.0)
    +    rails-dom-testing (2.0.1)
    ...
    -    webmock (2.0.3)
    +    webmock (2.1.0)
  • Now rerun the above rspec test and you get this:
     Failure/Error: get :index

     ActionDispatch::IllegalStateError:
       header already sent

Expected behavior

Expect the above test to run without the ActionDispatch::IllegalStateError error

Actual behavior

Get error:

     Failure/Error: get :index

     ActionDispatch::IllegalStateError:
       header already sent

The total stacktrace is here: https://gist.github.com/jasnow/358925716d2068145790b11e4615cd3e

System configuration

Rails version: Rails 5.1.0.alpha

  • Before: edge Rails: c4cb6862babd2665a65056e205c2a5fd17a5d99d
  • After:: edge Rails: 66ebbc4952f6cfb37d719f63036441ef98149418

Ruby version: ruby-2.3.1

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 8
  • Comments: 23 (8 by maintainers)

Commits related to this issue

Most upvoted comments

https://github.com/plataformatec/devise/pull/4169 appears to fix my original problem. The whole community thanks you. - @hamadata and @lucasmazza

I found a workaround for this issue. The tests in devise gem pass with this change.

diff --git a/lib/devise/test/controller_helpers.rb b/lib/devise/test/controller_helpers.rb
index 462f313..060630e 100644
--- a/lib/devise/test/controller_helpers.rb
+++ b/lib/devise/test/controller_helpers.rb
@@ -137,9 +137,8 @@ module Devise

           status, headers, response = Devise.warden_config[:failure_app].call(env).to_a
           @controller.response.headers.merge!(headers)
-          r_opts = { status: status, content_type: headers["Content-Type"], location: headers["Location"] }
-          r_opts[Rails.version.start_with?('5') ? :body : :text] = response.body
-          @controller.send :render, r_opts
+          @controller.status = status
+          @controller.response.body = response.body
           nil # causes process return @response
         end

Devise’s controller helpers seem to be triggering a call to the function process which in action_controller/test_case, it sets sent! which is what request.rb is checking to see if the header can be set…

/Users/sblackstone/code/rails/actionpack/lib/action_dispatch/http/response.rb:211:in `sent!'
/Users/sblackstone/code/rails/actionpack/lib/action_controller/test_case.rb:559:in `ensure in process'
/Users/sblackstone/code/rails/actionpack/lib/action_controller/test_case.rb:559:in `process'
/Users/sblackstone/.rvm/gems/ruby-2.3.1/gems/rails-controller-testing-0.1.1/lib/rails/controller/testing/template_assertions.rb:61:in `process'
/Users/sblackstone/.rvm/gems/ruby-2.3.1/bundler/gems/devise-ac702843ddaa/lib/devise/test/controller_helpers.rb:33:in `block in process'
/Users/sblackstone/.rvm/gems/ruby-2.3.1/bundler/gems/devise-ac702843ddaa/lib/devise/test/controller_helpers.rb:100:in `catch'
/Users/sblackstone/.rvm/gems/ruby-2.3.1/bundler/gems/devise-ac702843ddaa/lib/devise/test/controller_helpers.rb:100:in `_catch_warden'
/Users/sblackstone/.rvm/gems/ruby-2.3.1/bundler/gems/devise-ac702843ddaa/lib/devise/test/controller_helpers.rb:33:in `process'
/Users/sblackstone/code/rails/actionpack/lib/action_controller/test_case.rb:629:in `process_with_kwargs'
/Users/sblackstone/code/rails/actionpack/lib/action_controller/test_case.rb:381:in `get'

Then after this, _process_unauthenticated ends up calling render on ActionController and it sees the request as already sent… Not sure exactly what the change was tho that caused this after some cursory searching…

I encountered the same issue after the upgrade to rails-5.rc2 from the rails-5.rc1

Here you can see the stack trace: https://gist.github.com/dalpo/66824995f6b3509acad444d46fa42da2