복붙노트

[RUBY-ON-RAILS] RSpec에 컨트롤러 사양에서 사용하기 위해 소장 구성

RUBY-ON-RAILS

RSpec에 컨트롤러 사양에서 사용하기 위해 소장 구성

나는 내 컨트롤러 사양에서 사용자의 로그에 고안의 sign_in 방법을 사용할 수 있었다. 하지만 지금 내 응용 프로그램에서 고안을 제거하고 있습니다 것이 아니에요 확신 단지 자체에 소장과 유사한 기능의 작동을 얻는 방법.

어떻게 RB 파일입니다. 사양 / spec_helper.rb 및 관련 사양 / 지원 / * 설정에 대한 가야 소장은 충분히 컨트롤러 사양 내에서 실행 얻을?

나는이 내용 사양 / 지원 / warden.rb에서 파일을 설정하는 시도했다 :

RSpec.configure do |config|
  config.include Warden::Test::Helpers

  config.after do
    Warden.test_reset!
  end
end

그리고 내가 전에 사용자의 공장을 인증하기 위해 다음과 유사한 호출했다 :

before { login_as FactoryGirl.create(:user) }

그러나 여기에 내가 보는 유지하는 것이 오류는 다음과 같습니다

NameError:
  undefined method `user' for nil:NilClass

이 오류 추적을 내 authenticate_user에 다시! 상기 제어기에있어서,

def authenticate_user!
  redirect_to login_path, notice: "You need to sign in or sign up before continuing." if env['warden'].user.nil?
end

나는 누군가가 제공 할 수있는 지침을 감사하겠습니다.

해결법

  1. ==============================

    1.당신이 뭘 하려는지에 기본적인 문제가 있습니다. 소장은 랙 미들웨어이지만, 사양 이러한 유형의 전체 애플리케이션 스택을 실행하는 것을 의미하지 않는 한 RSpec에 컨트롤러 사양도, 랙에 포함되지 않습니다,하지만 컨트롤러 코드입니다. 당신은 사람들을위한 별도의 테스트와 미들웨어를 테스트 할 수 있지만이 경우에는, 나는 그것이 소장 자체가 작동하는지 테스트에 의미가 있다고 생각하지 않습니다.

    당신이 뭘 하려는지에 기본적인 문제가 있습니다. 소장은 랙 미들웨어이지만, 사양 이러한 유형의 전체 애플리케이션 스택을 실행하는 것을 의미하지 않는 한 RSpec에 컨트롤러 사양도, 랙에 포함되지 않습니다,하지만 컨트롤러 코드입니다. 당신은 사람들을위한 별도의 테스트와 미들웨어를 테스트 할 수 있지만이 경우에는, 나는 그것이 소장 자체가 작동하는지 테스트에 의미가 있다고 생각하지 않습니다.

    테스트하려면, 소장이 올바르게 구성되어 당신이 요구 사양 또는 통합 사양 (오이, 카피 바라 또는 유사한)를 사용한다고.

    이 컨트롤러 사양에 소장을 조롱하는 것은 기술적으로 가능하지만, 나는 크게 테스트 코드의 복잡성이 증가하면서 그것은 당신에게 많은 혜택을 제공하지 않는 생각합니다. 미들웨어는 스왑 미들웨어 용이하도록 투명한 방식으로 작동하는 의미와 같은처럼되어 랙 있음을 유의하십시오. 컨트롤러가 모두 한 소장에 직접 의존하지 않아야 그래서 당신의 컨트롤러에 대한 소장에서 테스트 의존성을 가지고, 실제로 (와 ApplicationController에 대한 아마는 예외) 깨진 캡슐의 표시이다.

    나는이 댓글이 도움이 될 것입니다 희망, 그래서 나는 최근이 같은 문제 다 퉜다.

  2. ==============================

    2.이 질문은 내 상황에 적용 생각하지 않았다, 그러나 그것은 수행합니다 스텁 소장을 컨트롤러 테스트에

    이 질문은 내 상황에 적용 생각하지 않았다, 그러나 그것은 수행합니다 스텁 소장을 컨트롤러 테스트에

    그것이 나오는 것에 따라 당신이 그것을 변통 몇 가지 마술을 할 필요가 있으므로, 소장은 RSpec에 컨트롤러 사양에 포함되지 않습니다.

    소장의 블로그 게시물에 대한 켄타로 이마이의 컨트롤러 검사 헬퍼는 특히 도움이되었다. 여기에 내가 RSpec을 위해 일을 가지고 방법입니다.

    1 단계 : 사양 / spec_helper / warden.rb를 만들고 켄타로가 고안에서 파생 된 이러한 내용에 붙여 넣습니다 :

    module Warden
      # Warden::Test::ControllerHelpers provides a facility to test controllers in isolation
      # Most of the code was extracted from Devise's Devise::TestHelpers.
      module Test
        module ControllerHelpers
          def self.included(base)
            base.class_eval do
              setup :setup_controller_for_warden, :warden if respond_to?(:setup)
            end
          end
    
          # Override process to consider warden.
          def process(*)
            # Make sure we always return @response, a la ActionController::TestCase::Behavior#process, even if warden interrupts
            _catch_warden {super} || @response
          end
    
          # We need to setup the environment variables and the response in the controller
          def setup_controller_for_warden
            @request.env['action_controller.instance'] = @controller
          end
    
          # Quick access to Warden::Proxy.
          def warden
            @warden ||= begin
              manager = Warden::Manager.new(nil, &Rails.application.config.middleware.detect{|m| m.name == 'Warden::Manager'}.block)
              @request.env['warden'] = Warden::Proxy.new(@request.env, manager)
            end
          end
    
          protected
    
          # Catch warden continuations and handle like the middleware would.
          # Returns nil when interrupted, otherwise the normal result of the block.
          def _catch_warden(&block)
            result = catch(:warden, &block)
    
            if result.is_a?(Hash) && !warden.custom_failure? && !@controller.send(:performed?)
              result[:action] ||= :unauthenticated
    
              env = @controller.request.env
              env['PATH_INFO'] = "/#{result[:action]}"
              env['warden.options'] = result
              Warden::Manager._run_callbacks(:before_failure, env, result)
    
              status, headers, body = warden.config[:failure_app].call(env).to_a
              @controller.send :render, :status => status, :text => body,
                :content_type => headers['Content-Type'], :location => headers['Location']
    
              nil
            else
              result
            end
          end
        end
      end
    end
    

    2 단계 : 사양 / spec_helper.rb에서 RSpec.configure 블록 내에서, 새로운 모듈을 포함하는 라인이 추가 :

    config.include Warden::Test::ControllerHelpers, type: :controller
    

    단계 3 : 이것은 유사한 블록 전에 사용 구문에서 사용자 로그인하려면

    before { warden.set_user FactoryGirl.create(:user) }
    

    4 단계 : 당신이 당신의 컨트롤러에서 request.env [ '소장']하지 ENV [ '소장'] 참조하는지 확인합니다. 후자는 테스트 환경에서 컨트롤러 사양에서 작동하지 않습니다.

    모자 나는 맥주 하루 빚 켄타로 이마이에 팁 (또는 다른 인생에서)!

  3. from https://stackoverflow.com/questions/13420923/configuring-warden-for-use-in-rspec-controller-specs by cc-by-sa and MIT license