2017-12-06 5 views
1

저는 Rspec을 처음 사용 했으므로 TDD를 시도하고 있습니다. 응용 프로그램 컨트롤러에는 현재 사용자 설정이라는 메서드가 있습니다.NoMethodError : 정의되지 않은 메소드 'id'for nil : NilClass

class ApplicationController < ActionController::Base 
    protect_from_forgery with: :exception 
    protected 
    def set_current_user 
     @current_user ||= User.find_by_session_token(cookies[:session_token]) 
     redirect_to login_path unless @current_user 
    end 
    end 

여기에 내가 테스트 쓴 BlogsController.rb

class BlogsController < ApplicationController 
    before_action :set_current_user 
    before_action :has_user_and_hobby 
    def blog_params 
    params.require(:blog).permit(:title, :hobby_id, :user_id, :body, :rating) 
    end 

... 

    def destroy 
    @blog = Blog.find(params[:id]) 
    if @blog.user_id != @current_user.id 
     flash[:notice] = "The blog #{@blog.title} only can be deleted by the author! It cannot be deleted by others." 
     redirect_to hobby_blogs_path(@blog) 
    else 
     @blog.destroy 
     flash[:notice] = "Blog '#{@blog.title}' deleted." 
     redirect_back(fallback_location: root_path) 
    end 
    end 
end 

그리고 RSpec에있는 파괴 경로는 다음과 같습니다 내가 사양을 실행하려고하면

require 'spec_helper' 
require 'rails_helper' 

describe BlogsController do 
    let(:fuser) { FactoryGirl.create(:fuser) } 
    let(:hobby) { FactoryGirl.create(:hobby)} 
    let(:blog) { FactoryGirl.create(:blog, hobby_id: hobby.id, user_id: fuser.id)} 
    let(:comment) { FactoryGirl.create(:comment)} 

... 

    describe 'delete a blog' do 
     before :each do 
      allow_any_instance_of(ApplicationController).to receive(:set_current_user).and_return(fuser) 
      allow_any_instance_of(BlogsController).to receive(:has_user_and_hobby).and_return(blog.user_id,hobby) 
      allow(User).to receive(:find).with(blog.user_id).and_return(blog.user_id) 

     it 'should redirect_back' do 
      delete :destroy, params:{:hobby_id =>hobby.id, :id => blog.id} 
      expect(response).to be_redirect 
     end 
    end 
end 

, 내가 할 오류 :

Failure/Error: if @blog.user_id != @current_user.id 
NoMethodError: 
    undefined method `id' for nil:NilClass 

이걸 어떻게 도와 줄지 알아? 모든 도움에 진심으로 감사드립니다.

답변

3

@current_user은 테스트에서 nil입니다.

여기에 문제가 있습니다.

allow_any_instance_of(ApplicationController).to receive(:set_current_user).and_return(fuser) 

set_current_user

실제로 리디렉션을 가능하게 한 다음 @current_user 변수에 1을 할당하고, 사용자 개체를 반환하지 않습니다.

그것은 훨씬 더 레일 방식이 방식으로 사용자를 설정 할 수있다 : 당신의 현재 로그인 한 사용자 참조 할 때

class ApplicationController < ActionController::Base 
    before_action :verify_current_user! 

    def current_user 
    @current_user || User.find_by_session_token(cookies[:session_token]) 
    end 

    def verify_current_user! 
    redirect_to login_path unless current_user 
    end 
end 

는 다음, current_user 메서드를 호출합니다. 값이 메모되므로 성능 저하가 없습니다. 테스트를 시도 할 때 current_user 메소드를 스터핑 할 수도 있습니다. 컨트롤러에서 @current_user 대신 항상 current_user으로 전화하십시오.

+0

작동합니다! 정말 고맙습니다! – amazingPuppy

관련 문제