Test a base (abstract) controller

controller, rspec, ruby-on-rails

Solution

I guess you're planning to test the `assigns`, `session` and `db` changes then, rather than the rendered view. You can redraw routes for your abstract controller, for testing purposes only (there's an example at https://gist.github.com/zilkey/543300).

To get round the problem of no view being rendered, I suggest you surround each `get`, `post`, `put` or `delete` with a block that rescues from the no-view-found error (I'd write a small helper function to do this). Provided your controller renders the view as its last step, you should still be able to check the assignments, session and db changes.

An alternative would be to write your tests to be for a specific instance of the abstract controller, and factor out the controller name and any data needed. That way you don't have the problems of functional testing against a non-functioning controller, and you keep it easy to rewrite your tests every 3 weeks.

Problem

I have a base controller with some functionality, that base controller is not accessible from the outside, no route matches it. Then, I extend that controller with other controllers to add extra functionality and with routes, I have 3 controllers extending that base controller just to define 3 methods on each one of them. I want to test the base controller, but I can't do ``` post :index ``` because there are no routes for that action (No route matches error) I don't want to add those test to one of those 3 controllers because they change a lot (the controller is used during a campaign of... 3 weeks and then deleted). Some code...: The base controller, CampaignController ``` class CampaignController < ApplicationController def index #some code... end def campaign_name raise('campaign_name missing') end def campaign_url raise('campaign_url missing') end #more actions.... end ``` One of the accesible controllers, SchoolCampaignController ``` class SchoolCampaignController < CampaignController def campaign_name 'school' end def campaign_url school_url end end ``` those controllers are basically that but sometimes I need to override one of the base actions So, what am I doing wrong? how can I properly test CampaignController? EDIT: I don't want to test those two methods that raise an error, I want to test index for example, or some of the other actions (not shown) I've tried with "response = controller.index" but it doesn't call the before filters and the response is not an http response, it's just the output of that command (I can't do expectations like... response.should render_template(xxxx) with that) EDIT 2: To bypass the routing error I've created the routes inside the test in a before(:all) block, then the routing is not a problem, but now, I get errors about non existing views (each accesible controller implements all views, but the abstract one have non)

Original source