How will you test web layer in Spring Boot using WebMvcTest annotation?

Carvia Tech | April 22, 2019 | 2 min read | 64 views | microservices-architecture


How will you test web layer in Spring Boot using WebMvcTest annotation?

In this tutorial we will write a Spring Boot based test class that tests the web layer of our application without loading the full Spring context. These tests are often used to verify single or multiple containers

Using @SpringBootTest in tests will load the full Spring application context but without the server. But we can narrow down the testing scope to just web layer by using @WebMvcTest annotation.

Using @WebMvcTest, Spring Boot will only instantiate the web layer, not the whole context. That means:

Using this annotation will disable full auto-configuration and instead apply only configuration relevant to MVC tests (i.e. @Controller, @ControllerAdvice, @JsonComponent, Converter/GenericConverter, Filter, WebMvcConfigurer and HandlerMethodArgumentResolver beans but not @Component, @Service or @Repository beans

We can ask for just one controller to be initialized using @WebMvcTest(GreetingController.class)

Let’s create a simple Spring Boot application with a controller and service layer

We can use https://start.spring.io to create a sample application.

spring initlaizer webmvctest
Using Spring Starter to create project

We are using gradle build system to manage the build dependencies.

build.gradle
plugins {
	id 'org.springframework.boot' version '2.1.4.RELEASE'
	id 'java'
}

apply plugin: 'io.spring.dependency-management'

group = 'com.shunya.tutorial'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

We will create a simple controller that has a /greeting endpoint, which invokes a service to capture the greeting response.

GreetingController.java
@Controller
public class GreetingController {

    private final GreetingService service;

    public GreetingController(GreetingService service) {
        this.service = service;
    }

    @RequestMapping("/greeting")
    @ResponseBody
    public String greeting() {
        return service.greet();
    }

}

Here is our dummy GreetingService which just returns a mocked response.

GreetingService.java
@Service
public class GreetingService {
    public String greet() {
        return "Hello World";
    }
}

Now lets write a simple class that will do the web layer testing for us:

WebMockTest.java
@RunWith(SpringRunner.class)
@WebMvcTest(GreetingController.class)
public class WebMockTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private GreetingService service;

    @Test
    public void greetingShouldReturnMessageFromService() throws Exception {
        when(service.greet()).thenReturn("Hello Mock");
        this.mockMvc
                .perform(get("/greeting"))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(content().string(containsString("Hello Mock")));
    }
}

The above test will instantiate GreetingController but not the GreetingService component.

We can see that WebMvcTest is often used along with @MockBean to create any collaborators required by our @Controller beans.


Top articles in this category:
  1. Spring Boot 2.0 Reactive Web Performance Metrics
  2. Custom banner in spring boot application
  3. Setting a Random Port in Spring Boot Application at startup
  4. Running Spring Boot app as a service in unix
  5. Run method on application startup in Spring Boot
  6. How to prevent duplicate form submission in Spring MVC
  7. What are different Bean Scopes in Spring?



Find more on this topic:
Spring Framework image
Spring Framework

Spring Framework - MVC, Dependency Injection, Spring Hibernate, Spring Data JPA, Spring Boot and Spring Cloud for Microservices Architecture.

Last updated 1 week ago


Recommended books for interview preparation:

This website uses cookies to ensure you get the best experience on our website. more info