Michael Smedberg
2005-Nov-17 02:53 UTC
How can I call a different controller from within a functional test
>From within a controller test, I can call a function in the controller likethis: get :index but how do I call a function in a different controller? I want to do this for a couple reasons. First I want to have my tests do a "real" login through my "user" controller. Second, my app supports redirects back to "where you were." For instance, if a user goes to url A, then to url B, they might be redirected back to A. If, instead, they go to C, then to B, they''ll be redirected back to C. To test this functionality, I need to set the "original" URL by going to an URL in another controller (the A or C), then go to the URL in the controller under test, and see that the redirect is to the original controller. I wrote some cheesy code to approximate the behavior I want. It looks like this: class Test::Unit::TestCase #MES- Send an HTTP message to the indicated controller via # the indicated method def http_to_controller(method, controller, action, params) #MES- Store the current controller backup_controller = @controller begin #MES- Swap in the indicated controller @controller = controller #MES- Send the HTTP message self.send(method, action, params) ensure #MES- Swap back in the controller @controller = backup_controller #MES- Remake the request, but save the session new_req = ActionController::TestRequest.new new_req.session = @request.session @request = new_req end end end and it can be called like this: http_to_controller(:get, UserController.new, :show, { :id => user_id }) But it doesn''t work quite right. In particular, the URLs are not always quite right, so a call to @request.request_uri returns an old value (in this example, it wouldn''t return the URL to the UserController method, it''d return the URL to whatever the previous call was. Any ideas? It seems like there''s got to be a cleaner and safer way to do this, but I haven''t been able to come up with it. _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Jarkko Laine
2005-Nov-17 07:31 UTC
Re: How can I call a different controller from within a functional test
On 17.11.2005, at 4.53, Michael Smedberg wrote:> >From within a controller test, I can call a function in the > controller like this: > > get :index > > but how do I call a function in a different controller? > > I want to do this for a couple reasons. > First I want to have my tests do a "real" login through my "user" > controller. > Second, my app supports redirects back to "where you were." For > instance, if a user goes to url A, then to url B, they might be > redirected back to A. If, instead, they go to C, then to B, > they''ll be redirected back to C. To test this functionality, I > need to set the "original" URL by going to an URL in another > controller (the A or C), then go to the URL in the controller under > test, and see that the redirect is to the original controller.You can split this up in parts. In (say) posts_controller_test you test that the user is redirected to the login action in user controller, unless @session[:user] exists. You should also test that the "return address" is saved somewhere (probably session, too, or you can also use the referrer). Then, in the user controller tests, you test that if the return address is set and login is valid, the user is redirected back to the correct place in the app. Back in posts_controller_test, you then check that if @session[:user] exists, everything works fine without redirects to login system. So you don''t really need to "go" to another url in your tests, as long as you can test that the needed session vars are set and that the redirection obeys them. //jarkko -- Jarkko Laine http://jlaine.net http://odesign.fi _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Peter Donald
2005-Nov-17 11:27 UTC
Re: How can I call a different controller from within a functional test
Hi there, On 11/17/05, Michael Smedberg <smedberg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> but how do I call a function in a different controller? > > I want to do this for a couple reasons. > First I want to have my tests do a "real" login through my "user" > controller....> Any ideas? It seems like there''s got to be a cleaner and safer way to do > this, but I haven''t been able to come up with it.I would suggest that you approach the problem in a different way. I find it much easier to test each controller/action in isolation from other actions. Where an action requires state from a previous action I pass the action in through the session parameter. For example, most of the actions in my current application require authentication. A client is authenticated if a valid user_id is stored in the session so that value needs to be in session for action to be successful. So an example where it is used would be the following that tests creation of a comment; post(:new, {:comment =>{:issue_id => 1, :description => description}}, {''user_id'' => 1} ) You could invoke multiple actions from multiple controllers but I would suggest that this makes test evolution hard and less fine grained. Hope that helps! -- Cheers, Peter Donald RealityForge.org: http://www.realityforge.org