2015-04-08 12 views
11

ŚrodowiskoWymyślaj i rspec-rails - Jak zalogować użytkownika w specyfikacji typu zamówienia (specyfikacje oznaczone typem:: request)?

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

W moim /spec/rails_helper.rb mam włączone Devise pomocników dla plików spec oznaczone z type: :controller i type: :request

specyfikację/rails_helper.rb

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 

Po skonfigurowaniu tej konfiguracji specyfikacja type: controller działa dobrze. Jednak po uruchomieniu type: request specyfikacje otrzymuję następujący błąd:

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 jest następujące

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

Mam świadomość, że @request instancja nie jest dostępna dla: widowisko typu żądanie i stąd problem.

Czy są dostępne jakieś pomoce umożliwiające zalogowanie użytkownika w: specyfikacji typu zlecenia podczas korzystania z Devise?

znalazłem podobnego problemu https://github.com/plataformatec/devise/issues/1114, tym reply do którego proponuje następujące:

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.

Ale chciałbym przechodzić przez rzeczywistą logowanie do specyfikacji, która wymaga zalogowanego użytkownika.

Dzięki.

Odpowiedz

23

Przy pomocy kilku stanowisk SO (proszę odnieść się do sekcji Referencje poniżej) Udało mi się osiągnąć pożądane rozwiązanie. Jestem delegowania poniżej mojego kodu pracy, w przypadku może pomóc innym patrząc na to samo:

SPEC/rails_helper.rb

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

niespełniającego/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 

Wciąż nie wiem, jak potwierdzić, że Warden pomyślnie zalogował użytkownika, tak jak możemy to zrobić w specyfikacji kontrolera Devise, podając expect(subject.current_user).to_not be_nil. Jeśli ktoś wie, jak to zrobić, proszę udostępnij.

Odniesienia

Dzięki

Jiggnesh

+0

Hi Jiggneshh Gohel Czy masz jakieś rozwiązanie: spodziewać (subject.current_user) .to_not be_nil –

+0

@Viktor Leonets Przepraszam, że nie mam teraz rozwiązania, ponieważ później go nie ścigałem. –

+0

Dziękujemy! Szukałem rozwiązania tego przez wiele godzin. Sądzę, że istnieją inne sposoby na uporządkowanie tego, co może być lepsze dla mnie (uważam, że ten sam efekt można osiągnąć dzięki pomocniczym pomocnikom i makrom dla specyfikacji zamówień w sposób określony przeze mnie w specyfikacji kontrolera w niektórych z tych przykładów. Nadal mam problem, ponieważ dostaję "nieprzyjemny rzut: strażnik", ale muszę rozwiązać ten problem również dla moich funkcji. – CJBrew

Powiązane problemy