开发者

Stubbing ApplicationController methods with RSpec

开发者 https://www.devze.com 2023-04-03 20:15 出处:网络
I am trying to stub authentication for a controller in rspec.When I stub the authorize method the test always passed no matter what the value I supply.

I am trying to stub authentication for a controller in rspec. When I stub the authorize method the test always passed no matter what the value I supply.

Controller:

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

    fl开发者_运维知识库ash[: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

Specs:

# 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

It seems like as soon as I stub :authorize, no matter what value is set, it always passes the before_filter. I thought it might be the protected/helper_method designations, but playing with those didn't change anything.

Why does stubbing :authorize with false cause the before_filter to pass?


I think you need to check WHAT is being rendered.

Looking at your code, if the call-chain does indeed stop when authorize returns false, then what is going to happen?

There is no redirect, or render call.

So it will be an empty response?

An empty response would still be a 200.

However, depending what version of Rails you're using, its possible in Rails 3.1 that a before_filter returning false no longer stops the chain.

Really, a before_filter that wants to stop the chain should do one of the following

  1. redirect somewhere
  2. render something
  3. raise something


I'll answer your last question Why does stubbing :authorize with false cause the before_filter to pass?

You're stubbing the method authorize, which literally stops all the code inside of it to be called but returns what you are explicitly returning with the stub.

It is working properly, because when you stub current_user to false then the authorize is called completely. I think your lasts tests are not actually testing anything for you but thats just my opinion.

0

精彩评论

暂无评论...
验证码 换一张
取 消