Finding it difficult to test a before_filter on my ApplicationController

Hi All,
I’m writing tests for my new rails app and I’ve run into a bit of a
brick
wall. I’m trying to write a test for my ApplicationController which has
a
simple authorize method. And when I try and run the test I’m hitting a
nil
object exception. Here’s what my ApplicationController looks like:

class ApplicationController < ActionController::Base
before_filter :authorize, :except => :login
helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection
for
details

Scrub sensitive parameters from your log

filter_parameter_logging :password

public
def authorize
unless User.find_by_id(session[:user_id])
session[:original_uri] = request.request_uri
flash[:notice] = “Please log in”
redirect_to :controller => ‘access_control’, :action => ‘login’
end
end
end

I’ve created a test for the Application Controller and tried to mock out
the
controller as much as possible but I don’t think I’ve covered
everything.

require ‘test_helper’

class ApplicationControllerTest < ActionController::TestCase

def setup
@controller = ApplicationController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@controller.session = ActionController::TestSession.new
end

require ‘test_helper’

class ApplicationControllerTest < ActionController::TestCase

def setup
@controller = ApplicationController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@controller.request = @request
@controller.response = @response
@controller.session = ActionController::TestSession.new
end

def test_authorize_works_when_user_logged_in
#setup
logged_in

@request.request_uri = “http://test.host/

#exercise
ApplicationController.new.authorize

#assertions
assert_equals @request_uri = “http://test.host/
end
end

When I run my tests this is what I get :

  1. Error:
    test_authorize_works_when_user_logged_in(ApplicationControllerTest):
    NoMethodError: You have a nil object when you didn’t expect it!
    You might have expected an instance of ActiveRecord::Base.
    The error occurred while evaluating nil.[]
    app/controllers/application_controller.rb:14:in authorize' functional/application_controller_test.rb:21:in test_authorize_works_when_user_logged_in’

Its failing on the line where I try to look up the user from the session
object.

Is there a better way to mock out the ApplicationController? Why
doesn’t
rails generate a test in the first place for the application controller
am I
barking up the wrong tree? I have execised this code from another
controller test but it doesn’t feel right to have to use another
controller
to test this, and in the future I can see it being awkward when I want
to
test locale or cookie functionality.

I’ve had a good search for this and found a lot of questions relating to
this but no good answers which leads me to believe that I’m missing an
obvious convention of rails around not testing the application
controller.

Any help or advise would be appreciated.


View this message in context:
http://old.nabble.com/Finding-it-difficult-to-test-a-before_filter-on-my-ApplicationController-tp28253771p28253771.html
Sent from the RubyOnRails Users mailing list archive at Nabble.com.

In my opinion this test belongs to the UserSession or User controller
cause you’re testing if a user is authorized not the application. You
just need to put it into the application controller for its
application-wide accessibility. Besides that I can’t find anything wrong
in the authorize function. Put it in an user test and it should work.

Marnen Laibow-Koser-2 wrote:

In my opinion this test belongs to the UserSession or User controller
cause you’re testing if a user is authorized not the application. You
just need to put it into the application controller for its
application-wide accessibility. Besides that I can’t find anything wrong
in the authorize function. Put it in an user test and it should work.

I’m not sure if I agree with you on that point. I have a user model and
an
AccessControlController (terrible name I know) which handles the
login/logout actions, and the user model handles encrypting the password
and
comparing a password against what’s in the database.

What I’m doing in this method is merely checking if the user_id is
present
in the session and if that’s a valid user id. If it is I do nothing, if
it
isn’t I retain the uri they were trying to hit and redirect to the login
page.

This is application wide behavior and I feel its correct as far as I
understand the rails pattern to keep it in the application_controller.

Whether this is the right or wrong place for it, is it possible to test
the
ApplicationController I should I just never put code into it?


View this message in context:
http://old.nabble.com/Finding-it-difficult-to-test-a-before_filter-on-my-ApplicationController-tp28253771p28254089.html
Sent from the RubyOnRails Users mailing list archive at Nabble.com.

Of course, you can keep it in the ApplicatonController. That’s what the
ApplicationController is for. I just wouldn’t test the
ApplicationController itself cause it doesn’t make sense to me and I
guess you’re not supposed to test it anyway since there’s no
application_test.rb or anything being created when you create a Rails
application :slight_smile:
I’d move the tests you have right now in your ApplicationController test
file to the UserController test or wherever you think it belongs to and
you should be fine.

Marnen Laibow-Koser-2 wrote:

I do not know about any design decisions but I do agree with Cojones to
move test_authorize_works_when_user_logged_in into the User or
AccessControl test.

I don’t mean to be pedantic when asking this, only want to have a better
understanding of the situation. But why do you feel that way? The
functionality belongs in the ApplicationController so surely it follows
that
any tests on that functionality should be in the
ApplicationControllerTest.

View this message in context:
http://old.nabble.com/Finding-it-difficult-to-test-a-before_filter-on-my-ApplicationController-tp28253771p28254388.html
Sent from the RubyOnRails Users mailing list archive at Nabble.com.

Marnen Laibow-Koser-2 wrote:

Yeah I guess that works, I’ve already exercised this code elsewhere its
just
seems cleaner to me to have a test as close to the code its testing as
possible. So when it eventually breaks in a few months time and I’ve
forgotten all about the fact that I couldn’t test in the
ApplicationController I wont be looking in the UserController for the
problem. I guess I can just drop a comment in stating that.

Anyone know if it was a deliberate design decision not to test the
ApplicationController or if there was a reason it couldn’t be done? Or
even
better if there’s a way to test it?


View this message in context:
http://old.nabble.com/Finding-it-difficult-to-test-a-before_filter-on-my-ApplicationController-tp28253771p28254234.html
Sent from the RubyOnRails Users mailing list archive at Nabble.com.

On Apr 15, 12:48 pm, BarryOg [email protected] wrote:

Anyone know if it was a deliberate design decision not to test the
ApplicationController or if there was a reason it couldn’t be done? Or even
better if there’s a way to test it?

Assuming for a moment (and I don’t know if this is true) that you
can’t test application controller directly, there’s no reason you
cannot create a subclass of ApplicationController that only exists in
your test and which you use to exercise the methods provided by
ApplicationController.

Fred

Frederick C.-2 wrote:

That’s a fair point, but it involves mocking out the
ApplicationController
and everything it relies on, that’s what the rails framework is there
for,
just curious why I can’t seem to access it.


View this message in context:
http://old.nabble.com/Finding-it-difficult-to-test-a-before_filter-on-my-ApplicationController-tp28253771p28255673.html
Sent from the RubyOnRails Users mailing list archive at Nabble.com.

Anyone know if it was a deliberate design decision not to test the
ApplicationController or if there was a reason it couldn’t be done? Or
even
better if there’s a way to test it?

I do not know about any design decisions but I do agree with Cojones to
move test_authorize_works_when_user_logged_in into the User or
AccessControl test.

Frederick C. wrote:

On Apr 15, 12:48�pm, BarryOg [email protected] wrote:

Anyone know if it was a deliberate design decision not to test the
ApplicationController or if there was a reason it couldn’t be done? �Or even
better if there’s a way to test it?

Assuming for a moment (and I don’t know if this is true) that you
can’t test application controller directly, there’s no reason you
cannot create a subclass of ApplicationController that only exists in
your test and which you use to exercise the methods provided by
ApplicationController.

As you’ve discovered, controller tests are painful. Forget about them
and use Cucumber features instead. You’ll be a lot happier.

Fred

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

On Apr 15, 3:02 pm, BarryOg [email protected] wrote:

That’s a fair point, but it involves mocking out the ApplicationController
and everything it relies on, that’s what the rails framework is there for,
just curious why I can’t seem to access it.

That’s not quite what I meant. What i meant was

class ApplicationControllerTest < ActionController::TestCase
class StubController < ApplicationController
def index
render :text => ‘index action’
end
end
tests ApplicationControllerTest::StubController

test “non logged in user should be redirected to login page” do
get :index
assert_redirected_to ‘/login’
end
end

No mocking involved!

Fred

Frederick C.-2 wrote:

end

Fred

Yeah no mocking involved if I’m testing a method with nothing in it but
I’m
testing a method with calls to the session object, request object, flash
object and redirect_to


View this message in context:
http://old.nabble.com/Finding-it-difficult-to-test-a-before_filter-on-my-ApplicationController-tp28253771p28257679.html
Sent from the RubyOnRails Users mailing list archive at Nabble.com.