Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing ApplicationController Filters, Rails

I'm trying to use rspec to test a filter that I have in my ApplicationController.

In spec/controllers/application_controller_spec.rb I have:

require 'spec_helper'
describe ApplicationController do
  it 'removes the flash after xhr requests' do      
      controller.stub!(:ajaxaction).and_return(flash[:notice]='FLASHNOTICE')
      controller.stub!(:regularaction).and_return()
      xhr :get, :ajaxaction
      flash[:notice].should == 'FLASHNOTICE'
      get :regularaction
      flash[:notice].should be_nil
  end
end

My intent was for the test to mock an ajax action that sets the flash, and then verify on the next request that the flash was cleared.

I'm getting a routing error:

 Failure/Error: xhr :get, :ajaxaction
 ActionController::RoutingError:
   No route matches {:controller=>"application", :action=>"ajaxaction"}

However, I expect that there a multiple things wrong with how I'm trying to test this.

For reference the filter is called in ApplicationController as:

  after_filter :no_xhr_flashes

  def no_xhr_flashes
    flash.discard if request.xhr?
  end

How can I create mock methods on ApplicationController to test an application wide filter?

like image 521
SooDesuNe Avatar asked Aug 09 '11 02:08

SooDesuNe


People also ask

How do I run a test case in Rails?

Or we can run a single test file by passing the bin/rails test command the filename containing the test cases. This will run all test methods from the test case. You can also run a particular test method from the test case by providing the -n or --name flag and the test's method name.

How do you run a Minitest in Rails?

To run a Minitest test, the only setup you really need is to require the autorun file at the beginning of a test file: require 'minitest/autorun' . This is good if you'd like to keep the code small. A better way to get started with Minitest is to have Bundler create a template project for you.

What type of test is not typical in a Rails application?

Integration. Don't try to test all the combinations in integration tests. That's what unit tests are for. Just test happy-paths or most common cases.


1 Answers

To test an application controller using RSpec you need to use the RSpec anonymous controller approach.

You basically set up a controller action in the application_controller_spec.rb file which the tests can then use.

For your example above it might look something like.

require 'spec_helper'

describe ApplicationController do
  describe "#no_xhr_flashes" do
    controller do
      after_filter :no_xhr_flashes

      def ajaxaction
        render :nothing => true
      end
    end

    it 'removes the flash after xhr requests' do      
      controller.stub!(:ajaxaction).and_return(flash[:notice]='FLASHNOTICE')
      controller.stub!(:regularaction).and_return()
      xhr :get, :ajaxaction
      flash[:notice].should == 'FLASHNOTICE'
      get :regularaction
      flash[:notice].should be_nil
    end
  end
end
like image 88
nmott Avatar answered Sep 25 '22 08:09

nmott