How to test controllers?

Hi,

Because of the nature of controllers, it not usual for a controller to return any value. So how would you test it?

Your controller should be doing very little. To test it, you’d pass it test data and check the mock model has been interacted with as expected.

Controllers are notoriously difficult to test with the way most frameworks are designed, directly rendering content inside controller actions and not returning anything. Most of the time, you end up creating a new request context and inspecting the response for specific elements you are checking for, like a call to the Events controller “index” method results in a 200 OK response code with a title of “Events”, etc. You can provide mock models, etc. but I wouldn’t go too far into that territory, because you wind up having to change your tests as often as you change the code inside your controllers when its not really necessary in most cases.

All in all, I would say if all the libraries you use are well designed and tested, you don’t have to do much testing for your actual controllers unless its an area that is likely to be a trouble spot in the future, or if you’re making an API that external sources depend on. With real-world projects, your biggest constraint is time, so its more an issue of diminishing returns and cost/benefit than your code being perfect and always fully tested.

Mock all of the objects and testing a controller is relatively simple. The problem is, not all the controller functionality can be mocked if you wish to truly test the controller framework.

For instance, depending on how your framework implements action forwarding, you may actually need to instantiate a few objects other than just the controller instance; For example you may need the front controller, dispatcher, router, etc - at which point you essentially need to implement a sandbox environement.

Any output or redirection would typically be captured in a response object which can be mocked or not, and later inspected to verify the controller did indeed redirect on error, etc.

Cheers,
Alex