This article focuses on how to test mock Controller requests in unit tests, along with how to test the output of the code log in a single test.

First, create a new Spring Boot project

A simple Spring Boot project is set up as shown in the above images

In the figure above, I created a Gradle project to manage Spring Boot. The structure of the project is shown below, on the left.

As an additional note, there is a script for gradlew /gradlew. Bat. MAC or Linux can run./gradlew build in the project’s current directory to build the entire project. Windows builds the entire project using the script gradlew. Bat or under Bash in Windows./gradlew build as well

In the figure above, the part marked in red is a code style specification constraint, indented line feeds, using Google Java Format.

For example, different people may use different operating systems to program, even if they use the same operating system, but the configuration of idea of each person is different. In addition, the code style of each person is different, so it is difficult to form a unified style in a project. So the Google Java format mentioned above was configured in the project, and everyone executed./gradlew spotlessApply before submitting the code, so that the entire project standardized the code according to the uniform coding style.

I have pasted the above configuration at the bottom for the reader’s convenience CTRL + C/CTRL + V

Id "com. Diffplug. Gradle. Spotless" version "of" 3.27.1 spotless Java {{target project. FileTree (project. RootDir) {include '**/*.java' } googleJavaFormat() } }Copy the code

Add a exclude file to exclude Spring Security from the main entry file of spring Boot Main

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication( exclude = { org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class }) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }}Copy the code

Create DemoConfiguration class

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@ComponentScan({"com.example.demo"})
@EnableAutoConfiguration
public class DemoConfiguration implements WebMvcConfigurer {}
Copy the code

The default rule for spring Boot scanning packages is to scan everything in the same directory as DemoApplication, because later we will create subdirectories to hold beans like Controller and Service, Therefore, the specified package on DemoConfiguration scans all files under com.example.demo, as shown in the following figure

Create a Controller folder and create a DemoController class under the folder

package com.example.demo.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api") @Slf4j public class DemoController { @GetMapping("/log") public String log() { log.info("test print log"); return "log"; }}Copy the code

In this Controller, a new HTTP GET request interface/API /log is created to implement the print test print log

At this point, we’ve created a new Spring Boot project and created a DemoController that provides the/API /log interface to the GET method.

Open DemoController on MAC and use CMD + Shift + T to quickly create the single-test DemoController test class

package com.example.demo.controller; import static org.junit.jupiter.api.Assertions.*; import com.example.demo.extensions.CaptureSystemOutput; import javax.validation.constraints.NotNull; 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 org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; @SpringBootTest @AutoConfigureMockMvc @CaptureSystemOutput class DemoControllerTest { @Autowired private MockMvc mockMvc; @Test void log(@NotNull CaptureSystemOutput.OutputCapture outputCapture) throws Exception { this.mockMvc .perform( MockMvcRequestBuilders.get("/api/log").header("key", "value").param("key", "value")) .andExpect(MockMvcResultMatchers.status().isOk()); assertTrue(outputCapture.toString().contains("test print log")); }}Copy the code

Header ().param() to simulate header and request parameters. We use spring Boot’s mockMvc to simulate a browser request, specifying the/API /log interface of the get method

After that, we verify that the expected interface return is 200, which is the single test of status.isok () after andExpect in the figure above

Here, I added an open source CaptureSystemOutput class at github.com/sbrannen/ju…

The main use of this class is to verify that the console log output is the desired output in our code.

This is how, in a single test, to test whether the business code, the log is printed properly.