Testing Controllers

After we learned how to test Models, we are going to talk about testing Controllers.

What is Controller?

Controller is a link between user and system. It’s represented by a single class. Main responsibility it has is to take care of the application flow. Controller should never have any business logic and should be pretty “dumb”. It should just call services and sometimes models that will do all the work.

So as controllers are not so smart what exactly should we test and what are some things we need to look out for when we are writing them?

So let’s pretend we have some login system in place. First we want to test what happens when user tries to log in with wrong username or password. It should return 403 Forbidden HTTP status and redirect to login screen.

We also know that in order to check if user is logged in, a call to session service method that checks that should be called and a second method that tries to make a session should be called also. Both should return false in our first scenario.

So let’s write that test. We are going to set up test class in first step as well.

So we mock authenticationService because we are not testing that layer of our application and we are not interested in concrete implementation of that class. We just want to mock it and see if methods are getting called as expected. If we would initialize Authentication Service we would be getting false test coverage percentage, because it would appear that we are calling Authentication Service even though we are not really testing anything there. So that is a big no-no.

We set request to be POST and we set some fake parameters. We fire up our controller into action and we assert that we get 403 HTTP Status code and appropriate JSON response.

Of course this is going to fail because we don’t have anything implemented. So let’s make tests green.

OK so now our first test is green but we are way ahead of our self’s. We already implemented whole function and we have two more scenarios to create. First one is that if user is already logged in we don’t want to have him passing first check and trying to log him in again.

Let’s write that test.

In this example we see that hasIdentity now returns true, so that means that the second method from authenticationService will never be called because our program will exit before that.

And the last scenario we have is that everything goes as planned and user enters correct username and password. So response should be 201 Session Created.

So now we have everything covered.

As you can see we only tested flow of program and HTTP response we get from Controllers. They should not do anything more than that.