문제

나는 Rspec의 새로운 것이고 나는 BDD 사고 방식에 들어가려고 노력하고 있으므로이 오류에 대해 꽤 튼튼합니다. 나는 테스트하려는 레일 엔진을 가지고 있습니다. 다음은 게시판입니다. 기본적으로 조치가되기 전에 코스 목록을 채우고 싶습니다.

class BulletinsController < ApplicationController
  before_filter :get_courses

  def new
    @bulletin = Bulletin.new(author_id: @user.id)
  end

 ...

 private
 def get_courses
   if @user.has_role? :admin
     @course_list = Course.all.sort_by(&:start_date)
   ...
   end
 end
.

응용 프로그램 컨트롤러에는 각 요청에서 실행할 수있는 몇 가지 방법이 있습니다. Current_User 메소드

에 액세스 할 수 있도록 호스트 응용 프로그램에 고안을 사용하고 있습니다.
class ApplicationController < ::ApplicationController
  before_filter :get_user
  ...
  def get_user
    @user = current_user
  end
  ...
end
.

여기에서는 실행하려고하는 사양입니다.

describe BulletinsController do
  routes { MyEngine::Engine.routes }
  before { controller.stub(:authenticate_user!).and_return true }
  before { controller.stub(:get_user).and_return (@user = create(:user)) }

  describe "GET #new" do
    it "assigns a new bulletin to @bulletin" do
      bulletin = create(:bulletin)
      controller.stub(:get_courses)
      get :new
      assigns(:bulletin).should eq(bulletin)
    end
  end 
end
.

사양을 실행하려고하면 오류가 발생합니다 :

NoMethodError: undefined method 'id' for nil:NilClass
.

@user가 게시판에서 호출 될 때 정의되지 않았기 때문에 이것을 얻는 것을 이해합니다. 그러나 Spec의 이전 블록이 get_user 필터를 밖으로 스위킹 한 후 @user 변수를 정의 할 것으로 생각했습니다. 콘솔의 공장을 테스트 할 때 적절한 연관성 (게시판 -> 저자, 게시판 -> 과정 등)으로 모든 것이 생성되는 것으로 보입니다.

@user 변수가 내 컨트롤러 코드로 운반되지 않는 이유에 대해 누락 된 것을 확신하지 못합니다. RSPEC에 대한 모든 통찰력 및 / 또는 좋은 자습서는 크게 감사 할 것입니다.

도움이 되었습니까?

해결책

나는 또한 current_user를 스텁해야하며, 충분 할만 큼 (get_user를 스터프 할 필요가 없다) :

before { controller.stub(:current_user).and_return (@user = create(:user)) }
.

그리고 나는 좋은 관행이 사용자를 보내는 것입니다 (한 번 이상 필요하면) :

routes { MyEngine::Engine.routes }
let!(:user) { create(:user) }
before { controller.stub(:current_user).and_return user }
.

개인 메소드에 액세스 할 수있는 경우 다음과 같이 시도 할 수 있습니다.

subject.send(:current_user=, user)
.

controller 대신 subject 일 수 있으므로 지원하는 버전이 확실하지 않습니다.

업데이트.사실, 개인적인 방법을 테스트하는 것은 정말 까다 롭습니다.current_userdevise가 다음과 같이 정의하는 것으로 확인합니다.

def current_#{mapping}
  @current_#{mapping} ||= warden.authenticate(scope: :#{mapping})
end
.

그래서 warden.authenticate를 다시 사용하여 tub user를 반환 할 수 있습니다.

allow_any_instance_of(Warden).to receive(:authenticate).and_return(create(:user))
.

다른 팁

Devise는 어떻게 작동하는지 이해하지 않는 한, 고안된 방법을 사용할 수있는 방법을 스테이블하려고 할 수 있습니다.

테스트하는 것이 좋습니다. 단순히 사용자가 자신의 문서에 따라 고정 된 테스트 도우미를 사용하여 로그인하는 것입니다. https://github.com/plataformatec/devise#test-helpers

describe BulletinsController do
  routes { MyEngine::Engine.routes }
  before { sign_in(user) }

  let!(:user) { create(:user) }

  describe "GET #new" do
    it "assigns a new bulletin to @bulletin" do
      bulletin = create(:bulletin)
      controller.stub(:get_courses)
      get :new
      assigns(:bulletin).should eq(bulletin)
    end
  end 
end
.

이 방법으로, 당신은 방법을 고안하고 그것을 던지는 것을 걱정할 필요가 없습니다.자신의 방법을 테스트하는 데 집중하십시오.:)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top