Java > Testing in Java > Integration Testing > Spring Boot Test

Spring Boot Integration Test with MockMvc

This snippet demonstrates integration testing with Spring Boot using MockMvc. MockMvc allows you to test your controllers in a simulated environment without starting a full-fledged server. It's useful for testing the web layer of your application in isolation while still performing integration-level tests.

Project Setup

Ensure you have a Spring Boot project set up with a REST controller. Include the spring-boot-starter-web and spring-boot-starter-test dependencies in your pom.xml or build.gradle. The spring-boot-starter-test provides MockMvc.

Example Controller

This is a very simple REST controller with a /hello endpoint that returns a static string.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello, World!";
    }
}

Integration Test using MockMvc

This integration test uses @SpringBootTest to load the application context and @AutoConfigureMockMvc to configure MockMvc. The mockMvc.perform() method simulates an HTTP request to the /hello endpoint. The andExpect() methods verify the HTTP status code and the content of the response.

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
public class HelloControllerIntegrationTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void helloShouldReturnHelloWorld() throws Exception {
        mockMvc.perform(get("/hello"))
                .andExpect(status().isOk())
                .andExpect(content().string("Hello, World!"));
    }
}

Concepts Behind the Snippet

This snippet demonstrates how to perform integration tests using MockMvc in Spring Boot. The key concept is simulating HTTP requests without needing a running server. This allows you to efficiently test your controllers and ensure they handle requests and responses correctly. @AutoConfigureMockMvc is essential for injecting the MockMvc instance, and mockMvc.perform() lets you construct and execute requests.

Real-Life Use Case Section

In a real-world scenario, you can use MockMvc to test various controller functionalities, such as handling different request parameters, validating request bodies, and returning different types of responses (JSON, XML, etc.). This ensures that your API endpoints function correctly according to your specifications.

Best Practices

  • Use descriptive test names to clearly indicate what is being tested.
  • Write tests that cover different scenarios and edge cases.
  • Use MockMvcResultHandlers.print() for detailed logging of request and response information during test execution, helpful for debugging.
  • Keep your tests concise and focused on a single aspect of controller behavior.

Interview Tip

Be prepared to explain the difference between MockMvc and TestRestTemplate. MockMvc is used for testing the web layer without a running server, while TestRestTemplate sends actual HTTP requests to a running server (either embedded or external). Know when to use each one based on your testing needs.

When to use them

MockMvc is ideal for testing the behavior of your controllers in a controlled environment. Use it when you need to test the handling of HTTP requests and responses, validate input, and ensure correct rendering of views without the overhead of a full server. This is especially useful for API testing.

Memory footprint

The memory footprint of MockMvc is relatively small because it doesn't start a full server. It only loads the necessary components for the web layer, making it efficient for testing.

Alternatives

Alternative approaches include using WebTestClient for testing reactive web applications, using Selenium for end-to-end testing that involves a real browser, or using a full-fledged server with TestRestTemplate.

Pros

  • Fast and efficient for testing the web layer.
  • Does not require a running server.
  • Provides fine-grained control over request and response simulation.

Cons

  • Does not test the entire application stack.
  • Requires careful setup of request parameters and expected responses.
  • May not catch integration issues between different layers.

FAQ

  • How do I test a POST request with a JSON body using MockMvc?

    You can use the MockMvcRequestBuilders.post() method and set the request body using content() and the content type using contentType(). Ensure you include the necessary dependencies for JSON processing (e.g., Jackson). For example:

    mockMvc.perform(post("/endpoint") .contentType(MediaType.APPLICATION_JSON) .content("{\"key\": \"value\"}") .andExpect(status().isOk());
  • How do I mock a service dependency in a MockMvc test?

    You can use @MockBean to replace a bean in the application context with a Mockito mock. Then, use Mockito.when() to define the behavior of the mock. For example:

    @MockBean private MyService myService; @Test public void test() throws Exception { when(myService.getData()).thenReturn("mocked data"); // Perform MockMvc request and assert results }