Integration Testing with Spring Boot

x
Integration testing with Spring Boot


Integration Testing with Spring Boot


Now that I have implemented a part of the API across all 3 layers, it’s time to write an integration test.

Integration Testing with Spring Boot

For the integration test, I want to send a get request to the API and it should go through all three layers and come back with a response, and this response will be asserted according to the expectations of the API.

Two approaches to Integration testing with Spring

  1. Start a server and send the request using the TestRestTemplate, provided by Spring.
Integration Testing with Spring Boot
  1. Use MockMVC to handle the HTTP request and pass it on to the Controller, the code will be executed exactly the same way as if it was processing a real HTTP request, but without the cost of having to start a server.
Integration Testing with Spring Boot

So I’m going to use the second approach in my integration tests. For this, I need the support of the MockMvc class.

Using the MockMvc I can perform GET, POST, AND DELETE operations.

The perform method will return a result as a ResultAction on which I can perform operations such as andDo, andReturn and andExpect.


Spring Boot testing annotations


The Test class should be annotated with the following annotations.

  1. @RunWith(SpringRunner.class)

  2. @SpringBootTest

  3. @AutoConfigureMockMvc

Example

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class CommentApiTest {


}

Let’s see why we need them.

@RunWith(SpringRunner.class)

This will bring Spring’s testing support to our JUnit test, such as loading the application context and auto wiring the beans.

This annotation is not required when using JUnit5

@SpringBootTest

This annotation tells the SpringRunner to start the application as a Spring Boot application.

By default, it does not start a server, instead, it loads a web ApplicationContext and provides a mock web environment. You can use the webEnvironment attribute if you want to set other options such as RANDOM_PORT, DEFINED_PORT, or NONE.

Read more at https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-testing-spring-boot-applications

Difference between @SpringBootTest and @WebMvcTest

@SpringBootTest will load the complete application and autowire all the beans, which makes it a bit slow.

Use @WebMvcTest if you only want to test the Controller layer and happy to mock all other dependencies, tests will run much faster.

@AutoConfigureMockMvc

This annotation auto-configures the MockMvc.


Spring Boot MockMvc Example


Following is the source code example of a very simple test using MockMvc.


package com.comment;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.hamcrest.Matchers.*;
import javax.inject.Inject;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.Sql.ExecutionPhase;
import org.springframework.test.context.jdbc.SqlGroup;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class CommentApiTest {

  @Inject
  private MockMvc mvc;

  @Before
  public void setUp() throws Exception {
  }

  @Test
  public void testCommentApiGetCommentsByPostId_statusOk() throws Exception {

    mvc.perform(get("/posts/1/comments")).andExpect(status().isOk());

  }


}