用于nil的未定义方法`cookie_jar':用于sign_in Rspec助手的NilClass

时间:2014-02-10 23:22:23

标签: ruby-on-rails ruby rspec ruby-on-rails-4 capybara

Rails: RSpec - undefined method `cookie_jar' for nil:NilClass我的问题有所不同,因为我在spec/requests目录中有我的规范。我跟随rails教程

  4) User Pages authorization as wrong user submitting a GET request to the Users#show action 
     Failure/Error: before { sign_in user, no_capybara: true }
     NoMethodError:
       undefined method `cookie_jar' for nil:NilClass
     # ./spec/support/utilities.rb:6:in `sign_in'
     # ./spec/requests/user_pages_spec.rb:77:in `block (4 levels) in <top (required)>'

spec/support/utilities.rb

include ApplicationHelper                                                                                                      

def sign_in(user, options={})                                                                                                  
  if options[:no_capybara]                                                                                                     
    remember_token = User.new_remember_token                                                                                   
    cookies[:remember_token] = remember_token                                                                                  
    user.update_attribute(:remember_token, User.encrypt(remember_token))                                                       
  else                                                                                                                         
    visit signin_path                                                                                                          
    fill_in "Email",    with: user.email                                                                                       
    fill_in "Password", with: user.password                                                                                    
    click_button "Sign in"                                                                                                     
  end                                                                                                                          
end 

spec/requests/user_pages_spec.rb

....
context "as wrong user" do                                                                                                 
  let(:user) { FactoryGirl.create(:user) }                                                                                 
  let(:wrong_user) { FactoryGirl.create(:user, email: 'wrong@example.com') }                                                                               
  before { sign_in user, no_capybara: true }                                                                               

  describe "submitting a GET request to the Users#edit action" do                                                          
    before { get edit_user_path(wrong_user) }                                                                              
    specify { expect(response.body).not_to match('Edit user') }                                                            
    specify { expect(response).to redirect_to(root_path) }                                                                 
  end                                                                                                                      

  describe "submitting a PATCH request to the Users#update action" do                                                      
    before { patch user_path(wrong_user) }                                                                                 
    specify { expect(response).to redirect_to(root_url) }                                                                  
  end                                                                                                                      

  describe "submitting a GET request to the Users#show action" do                                                          
    before {get user_path(wrong_user) }                                                                                    
    specify {expect(response.body).not_to match(user.name) }                                                               
    specify { expect(response).to redirect_to(root_path) }                                                                 
  end  
end

SessionController

class SessionsController < ApplicationController                                                                               

  def new                                                                                                                      
  end                                                                                                                          

  def create                                                                                                                   
    user = User.find_by(email: params[:email].downcase)                                                                        
    if user && user.authenticate(params[:password])                                                                            
      session[:user] = user.id                                                                                                 
      sign_in user                                                                                                             
      redirect_to user                                                                                                         
    else                                                                                                                       
      flash.now[:error] = 'Invalid email/password combination'                                                                 
      render 'new'                                                                                                             
    end                                                                                                                        
  end                                                                                                                          

  def destroy                                                                                                                  
    sign_out                                                                                                                   
    redirect_to root_path                                                                                                      
  end                                                                                                                          
end    

SessionsHelper

module SessionsHelper                                                                                                          

  def sign_in(user)                                                                                                            
    remember_token = User.new_remember_token                                                                                   
    cookies.permanent[:remember_token] = remember_token                                                                        
    user.update_attribute(:remember_token, User.encrypt(remember_token))                                                       
    self.current_user = user                                                                                                   
  end                                                                                                                          

  def signed_in?                                                                                                               
    !current_user.nil?                                                                                                         
  end                                                                                                                          

  def sign_out                                                                                                                 
    current_user.update_attribute(:remember_token, User.encrypt(User.new_remember_token))                                      
    cookies.delete(:remember_token)                                                                                            
    self.current_user = nil                                                                                                    
  end                                                                                                                          

  def current_user=(user)                                                                                                      
    @current_user = user                                                                                                       
  end                                                                                                                          

  def current_user                                                                                                             
    remember_token = User.encrypt(cookies[:remember_token])                                                                    
    @current_user ||= User.find_by(remember_token: remember_token)                                                             
  end                                                                                                                          
end                                                                                                                            

1 个答案:

答案 0 :(得分:3)

因此,发生这种情况的原因是cookies只是调用request.cookie_jar。因此,问题是requestnil

在被测控制器上模拟request,或者使用一些模拟请求进入控制器的内容。