ruby-on-rails - 未定义方法 `cookie_jar' 为 nil :NilClass for sign_in Rspec helper

标签 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

session Controller

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    

session 助手

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                                                                                                                            

最佳答案

所以,发生这种情况的原因是 cookies 只是调用了 request.cookie_jar。由此得出问题是 requestnil

要么在被测 Controller 上模拟 request,要么使用将请求模拟到 Controller 中的东西。

关于ruby-on-rails - 未定义方法 `cookie_jar' 为 nil :NilClass for sign_in Rspec helper,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21689988/

相关文章:

ruby-on-rails - ruby on rails group by 空值问题

ruby-on-rails - 如何在 ActionController::TestCase 请求中设置内容类型

ruby - ||= 在 Ruby 中是什么意思?

ruby-on-rails - Rails 希望我在每次更改时重新启动?

ruby - 将时间转换为其他时区

ruby-on-rails - 升级到 rspec 3 会导致使用时出错 should have(1).error_on

ruby - 如何模拟系统用户以测试 ruby​​ 中的文件系统交互?

ruby-on-rails - Ruby on Rails/ Bootstrap : dynamic datas in a modal

ruby-on-rails - 如何使用 Rspec 和 Capybara 测试重定向

mysql - ActiveRecord 根据自定义唯一性和最大列值进行选择