Skip to main content
 首页 » 编程设计

ruby-on-rails之完成教程时与 Cookie 相关的 rspec 测试问题

2024年12月31日15tuyile006

我一直在研究 Michael Hartl 的 Rails tutorial (顺便说一句,这真是太棒了)。

无论如何,一切都进展顺利,我已经接近第 10 章的结尾。问题是我的 rspec 测试已经开始产生一些失败,我无法弄清楚出了什么问题。

第一次失败发生在我处理the section on destroying users时。 。测试

before :each do 
  @user = Factory :user 
end 
 
describe "as a non-signed-in user" do 
  it "should deny access" do 
    delete :destroy, :id => @user 
    response.should redirect_to(signin_path) 
  end 
end 

给出错误:

UsersController DELETE 'destroy' as a non-signed-in user should deny access 
 Failure/Error: delete :destroy, :id => @user 
 NoMethodError: 
   undefined method `admin?' for nil:NilClass 
 # ./app/controllers/users_controller.rb:76:in `admin_user' 
 # ./spec/controllers/users_controller_spec.rb:308:in `block (4 levels) in <top (required)>' 

这是消息在 users_controller 中引用的代码:

def admin_user 
  # the error tels me that current_user = NilClass 
  redirect_to(root_path) unless current_user.admin? 
end 

所以我想这表明 current_user 无法正常工作并且被设置为 nil。现在 current_user 涉及 SessionsHelper 的许多方法,这些方法(据我所知)处理在安全 cookie 中设置用户 ID 并在用户在站点中移动时引用 cookie。所以这表明cookies有问题。

我已经检查了浏览器并且正在设置 cookie,我还检查了代码的每个部分,据我所知,它完全复制了教程。

还有什么我应该注意的吗?

附录

以下是 SessionsHelper 模块的内容:

module SessionsHelper 
 
    def sign_in user 
        # rails represents cookies as a hash and deals with the conversion for us 
        # making the cookie "signed" makes it impervious to attack 
        cookies.permanent.signed[:remember_token] = [user.id, user.salt] 
        # this line calls the assignment operator below 
        self.current_user = user 
      end 
 
      def current_user=(user) 
        @current_user = user 
      end 
 
      # this is a getter method 
      def current_user 
        # this sets @current_user = to the user corresponding to the remember token 
        # but only if @current user is undefined. ie it only works once 
        @current_user ||= user_from_remember_token 
      end 
 
    def signed_in? 
        # return true if current_user is not nil 
        !current_user.nil? 
      end 
 
      def sign_out 
        cookies.delete(:remember_token) 
        self.current_user = nil 
      end 
 
      def current_user? user 
        # returns true if the user object == the current_user object 
        user == current_user 
      end 
 
      def authenticate 
        deny_access unless signed_in? 
      end 
 
    def deny_access 
        store_location 
        # this is a shortcut for flash notices: flash[:notice] = "Please sign in to access this page." 
        redirect_to signin_path, :notice => "Please sign in to access this page." 
      end 
 
      def redirect_back_or(default) 
        redirect_to(session[:return_to] || default) 
        clear_return_to 
      end 
 
  private 
 
    def user_from_remember_token 
      # the * allows us to give a 2 element array to a method expecting 2 seperate arguments 
      User.authenticate_with_salt(*remember_token) 
    end 
 
    def remember_token 
      # return [nil, nil] if the :remember_token cookie is nil 
      cookies.signed[:remember_token] || [nil, nil] 
    end 
 
    def store_location 
      # stores the url the browser was requesting 
      session[:return_to] = request.fullpath 
    end 
 
    def clear_return_to 
      session[:return_to] = nil 
    end 
  end 

请您参考如下方法:

在您的规范中,ypu 正在尝试删除用户,而您尚未登录,因此 current_user 为零。您应该阻止用户访问未登录的此操作。

class UsersController < ApplicationController 
  before_filter :authenticate, :only => [:index, :edit, :update, :destroy] 
  .... 

正如示例中所描述的那样。