Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use Spring's Mock MVC when you have unit tets of your controller classes

I have seen people around me using Spring MVC in unit tests for controller classes, which is not helpful in what a unit test is for.

Unit tests are supposed to test your actual implementation of the controller class, and this can be achieved more accurately with simple Junit tests rather than using Spring Mock MVC.

But then the question arises, what's the real usage of Spring Mock MVC then? What do you need it for?

Let's say I have below code :

@Controller
@RequestMapping("/systemusers")
public class SystemUserController
{
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String getUser(final Model model)
    {

        // some logic to return user's details as json

        return UserDetailsPage;
    }
 }

I can test this class/controller more accurately with Junit than with Spring Mock MVC (all it does is generates some json which can be asserted with junit).

I can also test with Spring Mock MVC like using the correct endpoint returns the correct HTTP status and correct response page string.

But doesn't that mean that we are testing Spring MVC's functionality rather than the actual code for method under test?

P.S. : I have kept the code to minimal which I think is sufficient to explain my question. Assume there is no compilation error.

like image 839
Abubakkar Avatar asked Mar 31 '17 10:03

Abubakkar


2 Answers

When it comes to the unit-testing of a Controller (or any Endpoint which is exposed) classes, there are two things that we will validate:

(1) Controller's actual logic itself as standalone i.e., right service calls are invoked or not etc..

(2) Request URL mapping and the Response status & object

Item (1) above is what we test in general with all other classes like Services, Utility classes etc..

Item (2) needs to be covered/tested additionally for the endpoints (controller classes) which have been exposed, so whether we use Spring's MockMVC or other machinery to do that, it is up to us really.

Spring's MockMVC indeed helps us to start the in-memory servlet container & check that the right controller methods are invoked & then the right responses have been coming out.

From my personal experience, testing the controllers (for item(2)) helped me to resolve URL mapping conflict issues (of course, within the same controller) etc.. straight away rather than fixing them at the later stages of the project.

like image 50
developer Avatar answered Oct 06 '22 21:10

developer


Based on My experience I will try to answer your question.

First thing we need to understand why we use unit testing?

It is a extra check used by developer to write clean working code. Clean working code means every line written should be doing what it is expected to do. how do you achieve this? Here comes unit testing. The standalone unit of code you are writing should be verified standalone. Method is best part in code which represents standalone unit code template.

Unit Testing for Method

Developer should write a test for method which describes the method behavior. And possible checks that i follow is is it returning the expected value considering all positive scenarios? is it working in case of Exception? is it calling correct subsequent methods ?

Developer should verify the method by actually calling it providing a mock environment

Below is possible answer to your question. though it is solely based upon the developers.

Controller methods are intended to invoke correct service call accepting input and returning the value from service to view. So I may think of write a unit test case for controller method as you are thinking is a right approach. But you should verify the method by calling it in same way as it will be called in real time. so you need to call controller method in same way as MVC does. Hence it is better option to use MockMVC. MockMVC is also useful to verify the urls, input params , response and status which are part of controller method. Considering these all it makes it standalone unit of code.

Hope this will clarify your doubt.

like image 23
Dhiraj Avatar answered Oct 06 '22 22:10

Dhiraj