栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Boot工程测试之使用MockMvc进行UT,达到覆盖每一行代码的目标

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Boot工程测试之使用MockMvc进行UT,达到覆盖每一行代码的目标

1. 背景

基于Spring Boot的项目,公司强制要求必须写UT,否则不让提MR,而且要覆盖每一行代码。

2. 问题

因为要覆盖每一行代码,考虑到有些功能使用到了filter或者interceptor,所以采用在测试类中直接注入controller类的方式也满足不了。
例如:

@Resource
private UserController userController;
public void testGetUser(){
	userController.getXX();
}
3. 解决办法

使用MockMvc,可以从头到尾,测试一遍,就类似用户直接使用系统的感觉,帮助开发者覆盖到filter->interceptor->controller->service->dao的每一行代码。

废话不说,直接上代码

4. 工程结构

4.1 工程pom文件


    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.5.11
         
    
    com.xywei.springboot
    springtest-demo
    0.0.1-SNAPSHOT
    springtest-demo
    Demo project for Spring Boot with test
    
        1.8
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
        
    



4.2 MockMvc之Get请求+请求头 4.2.1 controller方法
    
    @GetMapping("/getUserById")
    public ResponseEntity getUserById(@RequestParam(value = "user_id", required = true) String userId,
                                                  @RequestHeader(value = "user_token") String userToken) {

        BaseResult baseResult = new BaseResult<>();
        User user = new User(userId, "whoami-" + userId.hashCode(), UUID.randomUUID().toString());
        baseResult.setCode(HttpStatus.OK.value());
        baseResult.setMessage(HttpStatus.OK.getReasonPhrase());
        baseResult.setData(user);

        return new ResponseEntity(baseResult, HttpStatus.OK);
    }
4.2.2 MockMvc测试
    @Test
    public void testGetUserById() {

        try {
            ResultActions perform = mockMvc.perform(
                    MockMvcRequestBuilders
                            .get("/getUserById") // 相当于postman输入请求地址
                            .param("user_id", "userId:998") // 相当于postman输入查询参数
                            .header("user_token", "为人民服务")// 相当于postman输入headers信息
            );
            String result = perform.andExpect(MockMvcResultMatchers.status().isOk())
                    .andReturn().getResponse().getContentAsString();
            ObjectMapper objectMapper = new ObjectMapper();
            BaseResult baseResult = objectMapper.readValue(result, BaseResult.class);
            Assert.notNull(baseResult.getData(), "expect not empty!");

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
4.3 MockMvc之POST请求+表单参数 4.3.1 controller方法
    
    @PostMapping("/getUserByUsernamePassword")
    public ResponseEntity getUserByUsernamePassword(String username, String password) {
        BaseResult baseResult = new BaseResult<>();
        User user = new User(UUID.randomUUID().toString(), username, password);
        baseResult.setCode(HttpStatus.OK.value());
        baseResult.setMessage(HttpStatus.OK.getReasonPhrase());
        baseResult.setData(user);
        return new ResponseEntity(baseResult, HttpStatus.OK);
    }
4.3.2 MockMvc测试
    @Test
    public void testGetUserByUsernamePassword() {
        try {
            ResultActions perform = mockMvc.perform(
                    MockMvcRequestBuilders
                            .post("/getUserByUsernamePassword") // 相当于postman输入请求地址
                            .param("username", "吃了八年的鱼") // 相当于postman输入表单参数
                            .param("password", "我为群众办实事") // 相当于postman输入表单参数
            );
            String result = perform
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    .andDo(MockMvcResultHandlers.print())
                    .andReturn().getResponse().getContentAsString();
            Assert.notNull(result, "should be not empty!");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
4.4 MockMvc之POST请求+JSON参数 4.4.1 controller方法
    
    @PostMapping("/insertUser")
    public ResponseEntity insertUser(@RequestBody List users) {
        BaseResult> baseResult = new BaseResult<>();
        baseResult.setCode(HttpStatus.OK.value());
        baseResult.setMessage(HttpStatus.OK.getReasonPhrase());
        baseResult.setData(users);
        return new ResponseEntity(baseResult, HttpStatus.OK);
    }

4.4.2 MockMvc测试
    @Test
    public void testInsertUser() {

        User user = new User(UUID.randomUUID().toString(), "群众第一", "为群众谋福利");
        List param = new ArrayList<>();
        param.add(user);
        try {
            String jsonData = new ObjectMapper().writeValueAsString(param);
            ResultActions perform = mockMvc.perform(
                    MockMvcRequestBuilders
                            .post("/insertUser") // 相当于postman输入请求地址
                            .contentType(MediaType.APPLICATION_JSON)
                            .content(jsonData)
            );
            String result = perform
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    .andDo(MockMvcResultHandlers.print())
                    .andReturn().getResponse().getContentAsString();
            Assert.notNull(result, "should be not empty!");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
4.5 完整的Tests代码
package com.xywei.springboot.springtestdemo;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xywei.springboot.springtestdemo.entity.User;
import com.xywei.springboot.springtestdemo.vo.BaseResult;
import org.junit.jupiter.api.Test;
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.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
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 org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@SpringBootTest
@AutoConfigureMockMvc
public class UserTests {

    @Resource
    private MockMvc mockMvc;

    @Test
    public void testGetUserById() {

        try {
            ResultActions perform = mockMvc.perform(
                    MockMvcRequestBuilders
                            .get("/getUserById") // 相当于postman输入请求地址
                            .param("user_id", "userId:998") // 相当于postman输入查询参数
                            .header("user_token", "为人民服务")// 相当于postman输入headers信息
            );
            String result = perform.andExpect(MockMvcResultMatchers.status().isOk())
                    .andReturn().getResponse().getContentAsString();
            ObjectMapper objectMapper = new ObjectMapper();
            BaseResult baseResult = objectMapper.readValue(result, BaseResult.class);
            Assert.notNull(baseResult.getData(), "expect not empty!");

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Test
    public void testGetUserByUsernamePassword() {
        try {
            ResultActions perform = mockMvc.perform(
                    MockMvcRequestBuilders
                            .post("/getUserByUsernamePassword") // 相当于postman输入请求地址
                            .param("username", "吃了八年的鱼") // 相当于postman输入表单参数
                            .param("password", "我为群众办实事") // 相当于postman输入表单参数
            );
            String result = perform
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    .andDo(MockMvcResultHandlers.print())
                    .andReturn().getResponse().getContentAsString();
            Assert.notNull(result, "should be not empty!");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testInsertUser() {

        User user = new User(UUID.randomUUID().toString(), "群众第一", "为群众谋福利");
        List param = new ArrayList<>();
        param.add(user);
        try {
            String jsonData = new ObjectMapper().writeValueAsString(param);
            ResultActions perform = mockMvc.perform(
                    MockMvcRequestBuilders
                            .post("/insertUser") // 相当于postman输入请求地址
                            .contentType(MediaType.APPLICATION_JSON)
                            .content(jsonData)
            );
            String result = perform
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    .andDo(MockMvcResultHandlers.print())
                    .andReturn().getResponse().getContentAsString();
            Assert.notNull(result, "should be not empty!");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

5 总结
  1. 已上代码基于所有大佬都有基础的条件,如有不懂,请自行查阅SpringBoot的使用。
  2. 代码中的Filter和Inteceptor太简单,所以没有给出,请自行配置,更好体验MockMvc。
  3. 未连接数据库,请自行配置。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/843336.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号