Boti Boti - 23 days ago 8
Ruby Question

How can I spec before_filters?

I want to spec my controllers before_filter with rspec.
I thought to use ActionController::Testing::ClassMethods#before_filters for it.

I got these results in my rails c:

2.0.0p353 :006 > ActionController::Base.singleton_class.send :include, ActionController::Testing::ClassMethods
2.0.0p353 :003 > EquipmentController.before_filters


=> [:process_action, :process_action]

But in reality this is the filter on my action:

class EquipmentController < ApplicationController
before_filter :authenticate_user!


Any ideas?

Answer

That's what I did in my project:

# 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

and than you can just use it in controller specs like this:

# spec/controllers/application_controller_spec.rb
require 'spec_helper'
describe ApplicationController do
  describe 'class' do
    it { has_before_filters(:authenticate_user) }
  end
end