Saturday, December 31, 2005

Testing Rails - Posting to another controller

I've spent a fair chunk of time this morning trying to get my functional tests on my rails app working with the login component. Here's the result of my time, presented in the hopes that it will help someone else who's stuck on the same thing.

I'm using ModelSecurity for the user login component because I'd also like to use the model security bits. Since I've got a before_filter to verify a user is logged in in my controller, I need to log in the user before I can test anything. Logging in the user is easy, right - I just post to the login action of the user controller. Here it is, wrapped in a function because I'll have to call it multiple times:

  def login_Neo
    post :login, :user=>{:login=>users(:neo).login, :password=>NEO_PASSWORD}

  def test_list
    get :list
    assert_response :success
    assert_template 'list'
    assert_not_nil assigns(:recipes)

Ok, I'm sure that I've got a problem because my controller doesn't have a login action, but I decided to run it and see what happens.

Expected response to be a <:success>, but was <302>

Yep, I'm being redirected to the user controller because of my before_filter.

Now, I know that I need to make it post to the user controller, not the recipedex controller. Much googling, reading and thinking later, I discover that the post method being used here is defined in ActionPack from Rails. And, once I dig up the source for that, I discovered that post simply uses the @controller instance variable.

Aha! One simple change and I'm on my way:

  def login_Neo
    controller_bak = @controller
    @controller =
    post :login, :user=>{:login=>users(:neo).login, :password=>NEO_PASSWORD}
    @controller = controller_bak

Now, it posts where I want it to, sets User.current as I expect and everything works!


Blogger frogliner said...

I was stuck on exactly the same problem, and your post was a great help. Thanks a lot.

4/04/2006 6:54 AM  

Post a Comment

<< Home