Unit Testing Spring MVC Controllers with REST Assured

The REST Assured test library for Java was recently updated to version 2.2 and one of the new features is support for unit testing Spring MVC controllers using the new spring-mock-mvc module. This module provides a substitute for the standard RestAssured API called RestAssuredMockMvc.

What can it do?

Using the RestAssuredMockMvc API you can unit test your controllers using the fluent API of REST Assured. It’s built on top of MockMvc from the Spring Web Test project. The example that we’ll look at in this blog is defined here:

where Greeting is a DTO defined as:

If you’re familiar with MockMvc from Spring then you know that you must initialize the MockMvc instance using standalone setup by passing in the Controllers that are of interest for the test or a full WebApplicationContext using webAppContextSetup. Using the RestAssuredMockMvc API it becomes very simple. In this example all we want to do is to unit test our GreetingController standalone so we need to initialize REST Assured with this controller. The full test looks like this:

Now imagine that you have multiple tests for the same Controller resource, for example you may want to verify the “id” and “content” in two different tests. In this case it’s not very DRY to repeat the standaloneSetup for every test. REST Assured address this by allowing you to define a standalone setup statically in a setup method:

which means that you can write the two tests without explicitly defining the standalone setup:

Why should I use this module?

You may wonder why you should use this module instead of testing the controller using the standard REST Assured API.

  • The most important aspect is that it’s simpler to get the environment started. You don’t need to bootstrap a container (for example Jetty or Tomcat), you simply initialize RestAssuredMockMvc with a context (for example a controller) and you’re ready to go.
  • Simplifies mocking. For example if we imagine that the GreetingController had a dependency to a service X you could just create a mock of X and pass that to the constructor of the GreetingController.
  • The tests are executed faster than having to go through a servlet container
  • You can test a controller in isolation, you don’t have to bootstrap your entire Spring application if you don’t want to.

Are there any benefits of using this API compared to the vanilla MockMvc API provided by Spring?

  • You don’t need to learn a new API if you’re already familiar with REST Assured. If you’ve used REST Assured before you may still find it useful since the standard REST Assured API (which is very similar) works for all kinds of backends, not just Spring MVC.
  • You can use the building blocks from REST Assured, for example request and response specifications, detailed configuration, root paths and so on.
  • The REST Assured API is more fluent which may be appealing to some users.
  • REST Assured provides a path syntax based on Groovy’s GPath which works in a similar way for both JSON, XML and HTML. Note that you can still use the Result Handlers supplied by Spring if you use the assertThat method provided by REST Assured.

When not to use it

RestAssuredMockMvc is not to be considered a complete replacement to vanilla MockMvc since it contains more specific features coupled to Spring MVC. For example right now there’s no first class support for things like flash attributes and principals. You can how ever add those by using an interceptor. Standard REST Assured also supports a lot of different authentication schemes and filters which are not available in the RestAssuredMockMvc API. Another reason for why you may want to use the standard REST Assured API is if it’s important to your organization to test the REST API in a real container (for example if you’ve configured authentication or authorization in a container specific manner) or if you’re using JAX-RS (or any other framework regardless of language).

Conclusion

The new spring-mock-mvc module provided by REST Assured allows you to virtually use the same API as REST Assured on top of Springs MockMvc. This has some nice benefits such as easier and faster startup etc. Please see the documentation for more info and the getting started guide for details on how to get started.

This Post Has 9 Comments

  1. Would be nice to see a complete code example.

    “If you’re familiar with MockMvc from Spring then you know that you must initialize the MockMvc instance using standalone setup by passing in the Controllers that are of interest for the test or a full WebApplicationContext using webAppContextSetup. ”

    No I’m not familiar with this setup.

    It would have taken less work to write this in code.

  2. Can you post your whole test class?

    I hit this error “java.lang.NoClassDefFoundError: com/jayway/restassured/config/Config”

    how to setup config?

  3. I have a question, anybody may answer; I’m knew into this and I understand the concept or Unit and Integration testing but when it comes to testing restful service, I don’t get the difference, instead it appears like functional testing to me because we are testing the url apis. So my question is what is the difference then between Unit and Integration test in restful services.

    1. What I mean in this context is that when you test a controller with MockMvc then you don’t need to use the underlying HTTP protocol. You test the controller directly and MockMvc just “simulates” an HTTP request (presumably by doing method invocations). If you use vanilla REST Assured you test the entire stack including the webserver and actual HTTP transmission.

  4. Can you give the example of running code with RestController with Service and crudrepository inside? I am asking because my code does not work according to this article.

    1. I don’t have such an example no. There are several working examples in the source code repository. Look in the “examples/spring-mvc-webapp” project.

  5. Thanks Johan,
    THis article is brilliant and its working like charm.
    I would love if you can help me,as how can I help testing ControllerAdvice that I have in my code for standalone setup.
    Is there a way we can add exceptionResolvers similar to MockMVC’s setHandlerExceptionResolvers??
    It would really help me,as I have all my exception handling in there.
    Thanks

  6. Now there is an equilalent utility in Spring Boot Test @WebMvc? What do you think are the advantages still using RestAssured?

    Thanks in advance

    1. @WebMvcTest

Leave a Reply

Close Menu