Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test a base (abstract) controller

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)

like image 323
arieljuod Avatar asked Mar 25 '13 17:03

arieljuod


1 Answers

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.

like image 155
hcarver Avatar answered Oct 25 '22 18:10

hcarver