1.test introduction
Software testing is a guarantee of application software quality. Developers developing interfaces often ignore interface unit testing. If you know how to mock unit tests, your number of bugs will be greatly reduced. Spring provides test module. Overall, the test types supported by Spring Boot Test can be roughly divided into the following three categories:
- Unit testing: Generally method-oriented, when writing general business code, the testing cost is relatively high. The annotations involved are @Test.
- Slice testing: Generally oriented to boundary functions that are difficult to test, between unit testing and functional testing. The annotations involved include @RunWith @WebMvcTest, etc.
- Functional testing: Generally oriented to a complete business function, you can also use the mocking capability in aspect testing, which is recommended. The annotations involved include @RunWith @SpringBootTest, etc.
Several key elements and support methods in the functional testing process are as follows:
- Test running environment: start the spring container through @RunWith and @SpringBootTest.
- Mock capability: Mockito provides powerful mock function.
- Assertion capabilities: AssertJ, Hamcrest, and JsonPath provide powerful assertion capabilities.
2.Code Project
Experiment purpose: verify controller and service layer logicpom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot-demo</artifactId>
<groupId>com.et</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
configurations
server:
port: 8088
username: default
server:
port: 8088
username: dev
cotroller
package com.et.test.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Map;
@Controller
public class HelloWorldController {
@RequestMapping("/hello")
@ResponseBody
public Map<String, Object> showHelloWorld(){
Map<String, Object> map = new HashMap<>();
map.put("msg", "HelloWorld");
return map;
}
}
service
package com.et.test.service;
import org.springframework.stereotype.Service;
/**
* @ClassName UserService
* @Description TODO
* @Author liuhaihua
* @Date 2024/4/4 13:13
* @Version 1.0
*/
public interface UserService {
public String getUserName();
}
package com.et.test.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* @ClassName UserServiceImpl
* @Description TODO
* @Author liuhaihua
* @Date 2024/4/4 13:16
* @Version 1.0
*/
@Service
public class UserServiceImpl implements UserService{
@Value("${server.username}")
private String username;
@Override
public String getUserName() {
return username;
}
}
DemoApplication.java
package com.et.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
The above are just some key codes. For all codes, please see the code repository below.
Code Repository
3.Test
Verify environment binding
@ActiveProfiles("dev")
You can switch to different environments and test in the same environment
Verify controller
@Test
public void bookApiTest() throws Exception {
// mockbean start
userServiceMockBean();
// mockbean end
String expect = "{\"msg\":\"HelloWorld\"}";
mockMvc.perform(MockMvcRequestBuilders.get("/hello"))
.andExpect(MockMvcResultMatchers.content().json(expect))
.andDo(MockMvcResultHandlers.print());
// mockbean reset
}
Verify service
@Test
public void execute() {
userServiceMockBean();
log.info("username:"+userService.getUserName());
Assertions.assertThat(userService.getUserName().equals("mockname"));
}
The following is the complete test code. If you are interested, you can test it.
package com.et.test;
import com.et.test.service.UserService;
import org.assertj.core.api.Assertions;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.BDDMockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import javax.annotation.Resource;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
@ActiveProfiles("dev")
@AutoConfigureMockMvc
public class DemoTests {
private Logger log = LoggerFactory.getLogger(getClass());
@Resource
private MockMvc mockMvc;
//@Autowired
@MockBean
UserService userService;
@Before
public void before() {
log.info("init some data");
}
@After
public void after(){
log.info("clean some data");
}
@Test
public void execute() {
userServiceMockBean();
log.info("username:"+userService.getUserName());
Assertions.assertThat(userService.getUserName().equals("mockname"));
}
@Test
public void bookApiTest() throws Exception {
// mockbean start
userServiceMockBean();
// mockbean end
String expect = "{\"msg\":\"HelloWorld\"}";
mockMvc.perform(MockMvcRequestBuilders.get("/hello"))
.andExpect(MockMvcResultMatchers.content().json(expect))
.andDo(MockMvcResultHandlers.print());
// mockbean reset
}
public void userServiceMockBean() {
BDDMockito.given(userService.getUserName()).willReturn("mockname");
}
}