单元测试、覆盖率测试-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不是必须有的,关键看被测试的方法中是否用到了这个方法,而且这个方法的结果是否需要被忽略。
    • 因为很多测试方法,只关心业务逻辑是否正常。
  • 执行覆盖率测试,即可得到和接口测试一样的结果
相关推荐
一 乐3 小时前
酒店预订|基于springboot + vue酒店预订系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·酒店预订系统
格鸰爱童话4 小时前
向AI学习项目技能(六)
java·人工智能·spring boot·python·学习
H_老邪5 小时前
spring boot 学习之路-1.0
spring boot·后端·学习
Flittly5 小时前
【SpringAIAlibaba新手村系列】(18)Agent 智能体与今日菜单应用
java·spring boot·agent
Andya_net5 小时前
Java | 基于 Feign 流式传输操作SFTP文件传输
java·开发语言·spring boot
成为大佬先秃头7 小时前
开放标准(RFC 7519):JSON Web Token (JWT)
spring boot·后端·json·jwt
不懂的浪漫8 小时前
# mqtt-plus 架构解析(八):Spring Boot 自动装配,这些零件是怎么被粘合起来的
spring boot·后端·物联网·mqtt·架构
却话巴山夜雨时i9 小时前
互联网大厂Java面试场景:Spring Boot、微服务与Redis实战解析
spring boot·redis·微服务·kafka·prometheus·java面试·电商场景
希望永不加班9 小时前
SpringBoot 配置绑定:@ConfigurationProperties
java·spring boot·后端·spring
indexsunny9 小时前
互联网大厂Java面试实战:Spring Boot、MyBatis与Kafka在电商场景中的应用
java·spring boot·面试·kafka·mybatis·电商·技术栈