使用RSpec对ApplicationController方法进行存根

时间:2011-09-10 23:22:44

标签: ruby-on-rails rspec

我正在尝试在rspec中为控制器存根身份验证。当我保留authorize方法时,无论我提供什么值,测试总是通过。

控制器:

class FoosController < ApplicationController
  before_filter :authorize
  ...
end

的ApplicationController:

class ApplicationController < ActionController::Base
  protect_from_forgery

  helper_method :current_user

  protected

  def authorize
    return true if current_user

    flash[:error] = 'Please login'
    redirect_to signin_path
    false
  end

  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end
end

规格:

# this passes (expected)
it "..." do
  controller.stubs(:current_user).returns(User.new)
  get :index
  response.should be_success
end

# this fails (expected)
it "..." do
  controller.stubs(:current_user).returns(nil)
  get :index
  response.should be_success
end

# this passes (expected)
it "..." do
  controller.stubs(:authorize).returns(true)
  get :index
  response.should be_success
end

# Problem: this passes (unexpected)
it "..." do
  controller.stubs(:authorize).returns(false)
  get :index
  response.should be_success
end

似乎只要我存根:授权,无论设置什么值,它总是通过before_filter。我认为它可能是protected / helper_method指定,但玩这些并没有改变任何东西。

为什么存根:使用false进行授权会导致before_filter通过?

2 个答案:

答案 0 :(得分:2)

我认为您需要检查正在呈现的内容。

查看代码,如果authorize返回false时调用链确实停止了, 那会发生什么?

没有重定向或渲染调用。

所以这将是一个空洞的回应?

空响应仍然是200。

但是,根据您使用的Rails版本,在Rails 3.1中可能会before_filter返回false不再停止链。

实际上,想要停止链的before_filter应该执行以下操作之一

  1. 重定向某处
  2. 渲染内容
  3. 提出一些事情

答案 1 :(得分:0)

我将回答您的上一个问题Why does stubbing :authorize with false cause the before_filter to pass?

您正在对方法授权进行存根,它实际上会停止调用它内部的所有代码,但会返回您使用存根显式返回的内容。

它工作正常,因为当您将current_user存根到false时,会完全调用授权。我认为你的持续测试实际上并没有为你测试任何东西,但这只是我的观点。