Reputation: 7474
We have a large application in Ruby on Rails with many filters. Some of these filters can be complex. I am looking for a way to individually test these filters with a unit test. Right now I test them by testing them through an action that uses them with a functional test. This just doesn't feel like the right way.
Does anyone have advice or experience with this?
Upvotes: 1
Views: 4507
Reputation: 301
You can testing with this code:
require "test_helper"
describe ApplicationController do
context 'ensure_manually_set_password' do
setup do
class ::TestingController < ApplicationController
def hello
render :nothing => true
end
end
NameYourApp::Application.routes.draw do
get 'hello', to: 'testing#hello', as: :hello
end
end
after do
Rails.application.reload_routes!
end
teardown do
Object.send(:remove_const, :TestingController)
end
context 'when user is logged in' do
setup do
@controller = TestingController.new
end
context 'and user has not manually set their password' do
let(:user) { FactoryGirl.build(:user, manually_set_password: false) }
setup do
login_as user
get :hello
end
should 'redirect user to set their password' do
assert_redirected_to new_password_path(user.password_token)
end
end
end
end
end
It's code is original from http://robots.thoughtbot.com/testing-a-before-filter, I changed for Rails 3
Upvotes: 1
Reputation: 28332
It depends on what your filters are doing.
This: http://movesonrails.com/journal/2008/1/23/testing-your-application-controller-with-rspec.html
And also learning how to use mocha will get you a long way.
Upvotes: 0
Reputation: 5962
I've come across this issue.
What about filters that perform actions requiring a request. i.e. using Flash
Example being Authlogic require_user method won't work just by using ApplicationController.new.send(:some_filter).
Anyone have some non-hack ideas on how to test this kind of thing in isolation? (I'm doing it by creating a extra dummy controller that I only use for testing.)
Upvotes: 0
Reputation:
I have a post on unit testing before_filters easily, you may wish to take a look. Hope it will help.
Upvotes: 1
Reputation: 7474
Orion I have messed with doing that in a few occurrences. Also, most of the time filters are private so you have to do a send:
SomeController.new.send(:some_filter)
Upvotes: 0
Reputation: 123662
Remember a filter is just a method.
Given this:
class SomeController
before_filter :ensure_awesomeness
...
end
There's no reason you can't just do this:
SomeController.new.ensure_awesomeness
and then check that it calls redirect_to or whatever it's supposed to do
Upvotes: 3