2015-04-08 12 views
11

Môi trườngphát sinh và rspec-ray - Cách đăng nhập người dùng trong Yêu cầu loại thông số kỹ thuật (thông số được gắn thẻ có loại:: 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 

Trong /spec/rails_helper.rb tôi Tôi đã bao gồm lập mưu giúp việc cho các tập tin đặc tả tagged with type: :controllertype: :request

đặc tả/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 

Với cấu hình đó, thông số kỹ thuật type: controller chạy tốt. Tuy nhiên khi chạy type: request số kỹ thuật Tôi nhận được lỗi sau:

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 đang theo

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

Tôi biết rằng dụ @request không có sẵn cho: thông số kỹ thuật yêu cầu loại và do đó lỗi.

Có bất kỳ người trợ giúp nào chúng tôi có thể sử dụng để đăng nhập người dùng trong: thông số loại yêu cầu khi sử dụng Devise không?

Tôi tìm thấy một vấn đề tương tự https://github.com/plataformatec/devise/issues/1114, các reply mà gợi ý sau:

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.

Nhưng tôi muốn bằng cách vượt qua đăng nhập thực tế cho thông số kỹ thuật mà đòi hỏi một người dùng đăng nhập.

Cảm ơn.

Trả lời

23

Với sự trợ giúp của vài bài đăng SO (vui lòng tham khảo Tham khảo phần bên dưới) Tôi đã đạt được giải pháp mong muốn. Tôi gửi bài mã làm việc của tôi dưới đây, trong trường hợp nó có thể giúp người khác tìm ra cho cùng:

đặc tả/rails_helper.rb

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

đặc tả/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 

Tôi vẫn chưa tìm ra cách để khẳng định Warden đã đăng nhập thành công vào người dùng như chúng ta có thể thực hiện trong thông số bộ điều khiển Devise bằng cách xác nhận expect(subject.current_user).to_not be_nil. Nếu ai biết cách để làm điều đó xin vui lòng chia sẻ.

Tài liệu tham khảo

Cảm ơn,

Jiggnesh

+0

Hi Jiggneshh Gohel Bạn có một số giải pháp cho: mong đợi (subject.current_user) .to_not be_nil –

+0

@Viktor Leonets Xin lỗi tôi không có bất kỳ giải pháp ngay bây giờ bởi vì tôi đã không theo đuổi nó sau đó. –

+0

Cảm ơn bạn! Tôi đã tìm kiếm một giải pháp cho điều này trong nhiều giờ. Tôi nghĩ rằng có nhiều cách khác để cấu trúc điều này có thể làm việc tốt hơn cho tôi (tôi tin rằng hiệu ứng tương tự có thể đạt được với người trợ giúp và macro cho Yêu cầu thông số kỹ thuật theo cách tôi đã thực hiện với thông số kỹ thuật của Bộ điều khiển trong một số ví dụ sau. Tôi vẫn còn có một vấn đề như tôi nhận được "ném vô tình: Warden" nhưng tôi phải giải quyết vấn đề đó cho thông số kỹ thuật của tôi quá. – CJBrew

Các vấn đề liên quan