我认为这个问题不适用于我的情况,但它确实适用:对 Warden 进行控制器测试 https://stackoverflow.com/questions/9261191/stubbing-warden-on-controller-tests
事实证明,Warden 并未包含在 RSpec 控制器规格中,因此您需要施展一些魔法才能将其纳入其中。
今井健太郎 https://stackoverflow.com/users/1222666/kentaro-imai's Warden 的控制器测试助手 http://kentaroimai.com/articles/1-controller-test-helpers-for-warden博客文章特别有帮助。以下是我如何让它适用于 RSpec。
Step 1: Create spec/spec_helper/warden.rb
并粘贴 Kentaro 从 Devise 导出的这些内容:
module Warden
# Warden::Test::ControllerHelpers provides a facility to test controllers in isolation
# Most of the code was extracted from Devise's Devise::TestHelpers.
module Test
module ControllerHelpers
def self.included(base)
base.class_eval do
setup :setup_controller_for_warden, :warden if respond_to?(:setup)
end
end
# Override process to consider warden.
def process(*)
# Make sure we always return @response, a la ActionController::TestCase::Behavior#process, even if warden interrupts
_catch_warden {super} || @response
end
# We need to setup the environment variables and the response in the controller
def setup_controller_for_warden
@request.env['action_controller.instance'] = @controller
end
# Quick access to Warden::Proxy.
def warden
@warden ||= begin
manager = Warden::Manager.new(nil, &Rails.application.config.middleware.detect{|m| m.name == 'Warden::Manager'}.block)
@request.env['warden'] = Warden::Proxy.new(@request.env, manager)
end
end
protected
# Catch warden continuations and handle like the middleware would.
# Returns nil when interrupted, otherwise the normal result of the block.
def _catch_warden(&block)
result = catch(:warden, &block)
if result.is_a?(Hash) && !warden.custom_failure? && [email protected] /cdn-cgi/l/email-protection(:performed?)
result[:action] ||= :unauthenticated
env = @controller.request.env
env['PATH_INFO'] = "/#{result[:action]}"
env['warden.options'] = result
Warden::Manager._run_callbacks(:before_failure, env, result)
status, headers, body = warden.config[:failure_app].call(env).to_a
@controller.send :render, :status => status, :text => body,
:content_type => headers['Content-Type'], :location => headers['Location']
nil
else
result
end
end
end
end
end
Step 2: In spec/spec_helper.rb
,在RSpec.configure
块,添加此行以包含新模块:
config.include Warden::Test::ControllerHelpers, type: :controller
Step 3:登录用户before
块,使用类似于以下的语法:
before { warden.set_user FactoryGirl.create(:user) }
Step 4:确保您引用request.env['warden']
在你的控制器中,而不是env['warden']
。后者在控制器规格中不起作用test
环境。
向今井健太郎致敬,我有一天(或在另一世)欠他一杯啤酒!