Bot*_*oti 2 ruby ruby-on-rails
我想用rspec指定我的控制器before_filter.我想为它使用ActionController :: Testing :: ClassMethods#before_filters.
我在导轨c中得到了这些结果:
2.0.0p353 :006 > ActionController::Base.singleton_class.send :include, ActionController::Testing::ClassMethods
2.0.0p353 :003 > EquipmentController.before_filters
Run Code Online (Sandbox Code Playgroud)
=> [:process_action,:process_action]
但实际上这是我行动的过滤器:
class EquipmentController < ApplicationController
before_filter :authenticate_user!
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
这就是我在项目中所做的:
# spec/support/matchers/have_filters.rb
RSpec::Matchers.define :have_filters do |kind, *names|
match do |controller|
filters = controller._process_action_callbacks.select{ |f| f.kind == kind }.map(&:filter)
names.all?{ |name| filters.include?(name) }
end
end
# spec/support/controller_macros.rb
module ControllerMacros
def has_before_filters *names
expect(controller).to have_filters(:before, *names)
end
end
# spec/spec_helper.rb
RSpec.configure do |config|
config.include ControllerMacros, type: :controller
end
Run Code Online (Sandbox Code Playgroud)
然后你可以在控制器规格中使用它,例如:
# spec/controllers/application_controller_spec.rb
require 'spec_helper'
describe ApplicationController do
describe 'class' do
it { has_before_filters(:authenticate_user) }
end
end
Run Code Online (Sandbox Code Playgroud)
我找到了一种基于ActionController :: Testing :: ClassMethods#before_filter的源代码的方法
这将是我的规格:
describe EquipmentController do
context 'authentication' do
specify{ expect(EquipmentController).to filter(:before, with: :authenticate_user!, only: :index)}
end
...
Run Code Online (Sandbox Code Playgroud)
这是我在spec/support/matchers/filter.rb中的匹配器
RSpec::Matchers.define :filter do |kind, filter|
match do |controller|
extra = -> (x) {true}
if filter[:except].present?
extra = -> (x) { x.options[:unless].include?( "action_name == '#{filter[:except]}'") }
elsif filter[:only].present?
extra = -> (x) { x.options[:if].include?( "action_name == '#{filter[:only]}'") }
end
controller._process_action_callbacks.find{|x|x.kind == kind && x.filter == filter[:with] && extra.call(x)}
end
end
Run Code Online (Sandbox Code Playgroud)