单元测试、覆盖率测试-Springboot

测试Controller

Maven依赖

xml 复制代码
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <scope>test</scope>
</dependency>
  • 如果被测试的方法中使用了springSecurity框架,需要引入其依赖

    xml 复制代码
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <scope>test</scope>
    </dependency>

测试类

  • 找到需要测试的接口,快捷键【 ctrl+shift+t 】,创建测试类

  • 创建测试类

  • 此时便会在test下指定位置生成测试类,然后补全

    java 复制代码
    package com.ruoyi.project.ices.visualization.controller;
    
    import com.ruoyi.RuoYiApplication;
    import lombok.SneakyThrows;
    import lombok.extern.log4j.Log4j2;
    import org.junit.jupiter.api.BeforeEach;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.MediaType;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.MvcResult;
    import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
    import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
    import org.springframework.test.web.servlet.setup.MockMvcBuilders;
    import org.springframework.util.LinkedMultiValueMap;
    import org.springframework.util.MultiValueMap;
    import org.springframework.web.context.WebApplicationContext;
    import java.nio.charset.StandardCharsets;
    import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
    import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
    
    //这里是Springboot启动类
    @SpringBootTest(classes = RuoYiApplication.class)
    @Log4j2
    class DrivingControllerTest {
    
        @Autowired
        private WebApplicationContext wac;
    
        private MockMvc mockMvc;
    
        private HttpHeaders headers;
    
        private static final String baseUrl = "/hard/xxxxxx";
        private static final String TOKEN = "Bearer eyJhbGciOiJxxxxxxxxxxxxx";
    
    		//下面全部方法测试执行前,都会先执行这里
        @BeforeEach
        public void init(){
            mockMvc = MockMvcBuilders
                    .webAppContextSetup(wac)
                    .apply(springSecurity())  // 关键:应用Spring Security配置
                    .alwaysDo(print())  // 打印请求响应信息,便于调试
                    .build();
            MultiValueMap<String, String> headerMap = new LinkedMultiValueMap<>();
            headerMap.add( "Authorization", TOKEN);
            headers = new HttpHeaders();
            headers.addAll(headerMap);
        }
    
        @SneakyThrows
        @Test
        void siteLocationList() {
            MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post(baseUrl+ "/xxxxxxxx")
                    .headers(headers)
                    .contentType(MediaType.APPLICATION_JSON))
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    .andReturn();
            String contentAsString = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
            log.info(contentAsString);
    
        }
    }
  • 执行覆盖率测试

  • 此时控制台查看日志

  • 右侧覆盖率测试

  • 如果要测试其他类型的方法

  • 如果要在请求体中传参数:

    java 复制代码
    @Autowired
    private ObjectMapper objectMapper; // JSON序列化
    @SneakyThrows
    @Test
    void edit() {
        // 创建请求体(Map方式)
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("id", "xxxxxxxx-a500-4d7d-8c08-088339e6d2c5");
        requestBody.put("remark", "测试修改内容");
        // 转换为JSON字符串
        String requestBodyJson = objectMapper.writeValueAsString(requestBody);
        MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.put(baseUrl)
                .headers(headers)
                .contentType(MediaType.APPLICATION_JSON)
                .content(requestBodyJson))  //设置请求体
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();
        String contentAsString = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
        log.info(contentAsString);
    }

白盒、单元测试service

Maven依赖

xml 复制代码
<!-- JUnit 5 -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <scope>test</scope>
</dependency>
<!-- Mockito -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>${mockito.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <scope>test</scope>
</dependency>

测试类

  • 和测试接口一样,创建测试类
java 复制代码
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@Slf4j
@ExtendWith(
MockitoExtension.class)  // JUnit 5 集成 Mockito
public class XXXXTest {
	//被测试service
    @InjectMocks
    private TestServiceImpl testService;
	
	//被Mock注解修饰的类,在测试方法中执行时,可以设置为代码桩
    @Mock
    private TestMapper testMapper;

	//测试方法传入的参数
	private TestVO query;
	//桩方法返回的结果
	private MockVO mockVO;
	
	@BeforeEach
	public void init(){
		// 这里会在每个方法执行之前执行
		//在这里初始化测试方法的参数
		query = new TestVO();
	
		//设置桩方法返回的结果
		mockVO = new MockVO();
		mockVO.setId(156l);
	}
	
	@Test
	@DisplayName("测试xx功能 - 正常情况")
	void test() {
	
	//模拟mapper的行为,在下面testService测试方法执行时,testMapper.selectTetsVO(mockVO)无论如何,都会返回thenReturn中的mockVO。
	when(testMapper.selectTetsVO(any(MockVO.class)))
                .thenReturn(mockVO );
	
	//执行测试方法
	String result = testService.test方法(query)

	log.info(result);

	// 验证,可以验证很多,这里仅验证了非空
	assertNotNull(result);
  
}
  • Mock不是必须有的,关键看被测试的方法中是否用到了这个方法,而且这个方法的结果是否需要被忽略。
    • 因为很多测试方法,只关心业务逻辑是否正常。
  • 执行覆盖率测试,即可得到和接口测试一样的结果
相关推荐
6***83059 分钟前
SpringBoot教程(三十二) SpringBoot集成Skywalking链路跟踪
spring boot·后端·skywalking
帅次24 分钟前
从开发到部署:软件实现、测试与交付全流程核心技术解析
功能测试·单元测试·测试用例·集成测试·压力测试·模块测试·安全性测试
Coder_Boy_32 分钟前
Flutter基础介绍-跨平台移动应用开发框架
spring boot·flutter
野生技术架构师41 分钟前
Spring Boot 4.0 预览版深度解析
java·spring boot·后端
Coder_Boy_1 小时前
Spring Boot 事务回滚异常 UnexpectedRollbackException 详解(常见问题集合)
java·spring boot·后端
期待のcode1 小时前
TransactionManager
java·开发语言·spring boot
计算机学姐1 小时前
基于SpringBoot的汽车租赁系统【个性化推荐算法+数据可视化统计】
java·vue.js·spring boot·后端·spring·汽车·推荐算法
好好研究2 小时前
SpringBoot小案例打包执行流程
java·spring boot·后端
rgeshfgreh2 小时前
Spring Bean管理机制深度解析
java·spring boot·spring
ling-452 小时前
ssm-day07 springboot3、Mybatis-Plus、springboot实战
java·spring boot·后端