How to check application controller before filtering methods in Rails 3?

Do I have a before_filter in my ApplicationController class and I want to write a test for it? Where should I write this test? I do not want to go into each test file of the subclass controller and repeat the test about this filter.

Therefore, what is the recommended way to test ApplicationController before_filters?

Please note that I am using Rails 3.2.1 with minitest .

+6
source share
4 answers

My case is slightly different from yours, but I needed to do something similar to site authentication (using Devise). Here is how I did it:

 # application_controller.rb class ApplicationController < ActionController::Base before_filter :authenticate_user! end # application_controller_test.rb require 'test_helper' class TestableController < ApplicationController def show render :text => 'rendered content here', :status => 200 end end class ApplicationControllerTest < ActionController::TestCase tests TestableController context "anonymous user" do setup do get :show end should redirect_to '/users/sign_in' end end 

If you have certain controllers that need to skip the filter before the filter, I will have a test to make sure they pass it in specific controller tests. This is not exactly your situation, as I am interested in the effect of the method, not only knowing that it was called, but I thought I would share it if you find it useful.

+5
source

Improving your work with @bmaddy answser, you need to configure routing to run specifications.

Here is a working example of rails 5:

 require 'test_helper' class BaseController < ApplicationController def index render nothing: true end end class BaseControllerTest < ActionDispatch::IntegrationTest test 'redirects if user is not logedin' do Rails.application.routes.draw do get 'base' => 'base#index' end get '/base' assert_equal 302, status assert_redirected_to 'http://somewhere.com' Rails.application.routes_reloader.reload! end test 'returns success if user is loggedin' do Rails.application.routes.draw do get 'base' => 'base#index' end mock_auth! get '/base' assert_equal 200, status Rails.application.routes_reloader.reload! end end 
+2
source

Now I believe that I need all of my benchmarks to test the existence of before_filter and that this filter works as expected. This is because I don't know if the controller skip_before_filter if it shouldn't.

Therefore, I decided to use mock ( @controller.expects(:before_filter_method) ) to make sure the filter is called. So, for example, in the index action, I write in my test:

 test "get index calls the before filter method" do @controller.expects(:before_filter_method) # fire get :index end 

This ensures that my controller will call before_filter_method for a specific action. I have to do this in all my action tests.

If anyone else has a better solution, let me know.

+1
source

Usually, when I want something like this, I just check the expected behavior, not taking into account that this specific behavior can be implemented in the filter, and not in the method itself. So, for the following simple scenario:

 class Controller < ApplicationController before_filter :load_resource, :only => [:show, :edit] def show end def edit end def index end ######### protected ######### def load_resource @resource = Model.find(params[:id]) end end 

I would try to verify that #show and #edit are set to @resource. This is very convenient for simple scenarios. If the filter is applied to many actions / controllers, you can extract the test code and reuse it among the tests.

0
source

Source: https://habr.com/ru/post/910973/


All Articles