2015-04-08 6 views
11

Umweltdevise und rspec-rails - Wie man Benutzer in Request Typ Spezifikationen (Spezifikationen mit Typ:: Anfrage)?

Rails 4.2.0 
ruby-2.2.1 [ x86_64 ] 
devise   3.4.1 
rspec-core 3.2.2 
rspec-rails 3.2.1 

In meinem /spec/rails_helper.rb ich Devise Helfer für spec-Dateien mit type: :controller und type: :request

spec/rails_helper.rb

getaggt enthalten sind,
ActiveRecord::Migration.maintain_test_schema! 

RSpec.configure do |config| 
    # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures 
    config.fixture_path = "#{::Rails.root}/spec/fixtures" 

    # If you're not using ActiveRecord, or you'd prefer not to run each of your 
    # examples within a transaction, remove the following line or assign false 
    # instead of true. 

    config.use_transactional_fixtures = false 

    config.before(:suite) do 
    DatabaseCleaner.strategy = :transaction 
    DatabaseCleaner.clean_with(:truncation) 
    end 

    config.before(:suite) do 
    begin 
     DatabaseCleaner.start 
     FactoryGirl.lint 
    ensure 
     DatabaseCleaner.clean 
    end 
    end 

    config.around(:each) do |example| 
    DatabaseCleaner.cleaning do 
     example.run # ==================> L-60 
    end 
    end 

    config.include FactoryGirl::Syntax::Methods 

    # RSpec Rails can automatically mix in different behaviours to your tests 
    # based on their file location, for example enabling you to call `get` and 
    # `post` in specs under `spec/controllers`. 
    # 
    # You can disable this behaviour by removing the line below, and instead 
    # explicitly tag your specs with their type, e.g.: 
    # 
    #  RSpec.describe UsersController, :type => :controller do 
    #  # ... 
    #  end 
    # 
    # The different available types are documented in the features, such as in 
    # https://relishapp.com/rspec/rspec-rails/docs 
    config.infer_spec_type_from_file_location! 

    config.include Devise::TestHelpers, type: :controller 
    config.include Devise::TestHelpers, type: :request 

end 

Mit dieser Konfiguration in Ordnung die type: controller Spezifikationen läuft gut. Doch beim Laufen type: request specs ich folgende Fehler bekommen:

Failure/Error: Unable to find matching line from backtrace 
NoMethodError: 
    undefined method `env' for nil:NilClass 
# /home/.rvm/gems/[email protected]/gems/devise-3.4.1/lib/devise/test_helpers.rb:24:in `setup_controller_for_warden' 
# ./spec/rails_helper.rb:60:in `block (3 levels) in <top (required)>' 
# /home/.rvm/gems/[email protected]/gems/database_cleaner-1.4.1/lib/database_cleaner/generic/base.rb:15:in `cleaning' 
# /home/.rvm/gems/[email protected]/gems/database_cleaner-1.4.1/lib/database_cleaner/base.rb:92:in `cleaning' 
# /home/.rvm/gems/[email protected]/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:86:in `block (2 levels) in cleaning' 
# /home/.rvm/gems/[email protected]/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:87:in `call' 
# /home/.rvm/gems/[email protected]/gems/database_cleaner-1.4.1/lib/database_cleaner/configuration.rb:87:in `cleaning' 
# ./spec/rails_helper.rb:59:in `block (2 levels) in <top (required)>' 

https://github.com/plataformatec/devise/blob/master/lib/devise/test_helpers.rb#L24 folgt

def setup_controller_for_warden #:nodoc: 
    @request.env['action_controller.instance'] = @controller # ==================> L-24 
end 

ich weiß, dass @request Instanz nicht verfügbar ist für: Anforderungstyp-Spezifikationen und damit den Fehler.

Gibt es Helfer, die wir verwenden können, um einen Benutzer zu registrieren in: Anfrage Typ Spezifikationen bei der Verwendung von Devise?

fand ich ein ähnliches Problem https://github.com/plataformatec/devise/issues/1114, um die reply die folgenden schlägt vor:

If you're doing integration tests, make sure to sign in your user in the tradicional way, by filling the sign in form and submitting.

Aber ich möchte die aktuelle Login für Spezifikationen passieren, die einen angemeldeten Nutzers erfordert.

Danke.

Antwort

23

Mit Hilfe von wenigen SO-Posts (siehe Abschnitt unten) habe ich es geschafft, die gewünschte Lösung zu erreichen. Ich veröffentliche meinen Arbeits Code unten, falls es kann andere helfen, mit Blick für das gleiche:

spec/rails_helper.rb

RSpec.configure do |config| 
    .... 
    .... 
    config.include Devise::TestHelpers, type: :controller 
    config.include Warden::Test::Helpers, type: :request 
    end 

spec/shared_contexts.rb

RSpec.shared_context "api request global before and after hooks" do 
    before(:each) do 
     Warden.test_mode! 
    end 

    after(:each) do 
     Warden.test_reset! 
    end 
    end 

    RSpec.shared_context "api request authentication helper methods" do 
    def sign_in(user) 
     login_as(user, scope: :user) 
    end 

    def sign_out 
     logout(:user) 
    end 
    end 

/spec/requests/api/logout_spec.rb

require 'rails_helper' 
    require 'shared_contexts' 


    RSpec.describe "Api Logout", :type => :request do 
    include_context "api request authentication helper methods" 
    include_context "api request global before and after hooks" 

    let(:email) { '[email protected]' } 
    let(:password) { 'password' } 

    # Assumes you have FactoryGirl included in your application's test group. 
    let!(:user) { create(:user, email: email, password: password) } 

    context "DELETE /logout" do 
     it "responds with 204 and signs out the signed-in user" do 
     sign_in(user) 

     # Till not figured out how to assert Warden has successfully logged in the user like we can do in a Devise controller spec by asserting subject.current_user. If anybody knows a way to do it please share. 
     # expect(subject.current_user).to_not be_nil 

     delete "/logout" 

     expect(response).to have_http_status(204) 
     end 
    end 
    end 

Ich habe immer noch nicht herausgefunden, wie man behauptet, Warden hat sich erfolgreich in den Benutzer eingeloggt, wie wir in einer Devise Controller-Spezifikation tun können, indem wir expect(subject.current_user).to_not be_nil geltend machen. Wenn jemand einen Weg kennt, es zu teilen, bitte teilen.

Referenzen

Danke,

Jiggnesh

+0

Hallo Jiggneshh Gohel Sind Sie eine Lösung haben für: erwarten (subject.current_user) .to_not be_nil –

+0

@Viktor Leonets Entschuldigung, ich habe momentan keine Lösung, weil ich sie danach nicht verfolgt habe. –

+0

Vielen Dank! Ich suchte stundenlang nach einer Lösung. Ich denke, es gibt andere Möglichkeiten, dies zu strukturieren, die für mich besser funktionieren könnten (ich glaube, der gleiche Effekt könnte mit Support-Helfern und Makros für Request-Spezifikationen erreicht werden, wie ich es mit Controller-Spezifikationen in einigen dieser Beispiele gesehen habe. Ich habe immer noch ein Problem, wenn ich "uncaught throw: Warden" bekomme, aber ich muss das Problem auch für meine Feature-Spezifikationen lösen. – CJBrew

Verwandte Themen