Capybara, Devise, CanCan and RSpec integration tests: valid sign in 302 redirects to example.com

后端 未结 1 1203
一生所求
一生所求 2021-01-14 11:35

Update: see end of post for how the specs now work now that I have my specs in spec/requests instead of spec/controllers. Still wondering how to get a valid signed in user f

1条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-14 12:07

    There are two issues at play:

    1. rspec/controller vs rspec/requests

    I was attempting to do an integration test under spec/controller. As per https://github.com/jnicklas/capybara#readme, you need to put Capybara specs in spec/requests or spec/integration. As per https://stackoverflow.com/a/5803121/9344:

    A request spec is a thin wrapper around ActionDispatch::IntegrationTest, which doesn't work like controller specs (which wrap ActionController::TestCase). Even though there is a session method available, I don't think it is supported (i.e. it's probably there because a module that gets included for other utilities also includes that method).

    Originally this could be solved with Devise via a helper method something like:

    # file: spec/requests_helper.rb
    def login(user)
      post_via_redirect user_session_path, 'user[email]' => user.email, 'user[password]' => user.password
    end
    

    But the official/latest solution, which I had implemented already (but see point two below for why it didn't solve my issue), can be found at https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara

    2. Devise::HelperTests are for controller/view tests, not integration tests.

    If I want to do some tests on a controller, I can use the Devise::TestHelpers (referenced via spec_helper.rb) but even then I don't get functionality for Capybara integration tests as the Devise::TestHelpers are specifically written for controller/view tests, not integration tests. See rspec & devise test helpers.

    In summary, what I wanted to do in a controller test can't be done because it was really an integration test and the session etc. isn't available for use in spec/controllers. However, there are some Devise test helpers that can be used to help do controller/view tests.

    UPDATE

    I revisited this much later, and have now got the Warden helpers functioning on my integration tests. Hurrah! This has taken off 8-10 seconds on my 448 tests. The trick was a new entry on https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara. Specifically:

    Capybara-Webkit

    If you have trouble using Warden's login_as method with the capybara-webkit driver, try setting run_callbacks to false in the login_as options struct

    user = Factory.create(:user) 
    login_as(user, :scope => :user,
    :run_callbacks => false)
    

    In summary, instead of having to do an actual form fill and post for each time I needed an authenticated user for an integration test, now I just need login_as(user, :scope => :user, :run_callbacks => false) (of course refactored out into a helper method).

    0 讨论(0)
提交回复
热议问题