Spring编写单元测试的工具介绍:JUnit、Mockito、AssertJ

背景:

在Spring应用程序中,想要通过代码走查做好测试左移,单元测试是确保代码质量和功能正确性的关键。除了我们常用的TestNG外,本次介绍一下其他常见的单元测试工具: JUnit、Mockito、AssertJ,来提高我们做白盒测试的效率。

一、引入依赖

在Maven项目中,我们通过添加以下依赖来引入使用

1、JUnit

JUnit是最常用的Java单元测试框架之一,它提供了丰富的API来编写和组织测试用例。

<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.9.1</version><scope>test</scope>
</dependency>

2、Mockito

Mockito允许我们创建模拟对象,并定义它们在测试中的行为。例如,我们可以模拟静态方法、构造函数或私有方法。可以用于模拟各个外部接口或者属性方法的数据。

<dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>4.8.1</version><scope>test</scope>
</dependency>

3、AssertJ

AssertJ提供了丰富的断言方法,使得断言更加简洁和易读。它支持链式断言和软断言,使得测试代码更加清晰。

<dependency><groupId>org.assertj</groupId><artifactId>assertj-core</artifactId><version>3.24.2</version><scope>test</scope>
</dependency>

二、常见模拟用法

1. 静态类

使用MockedStatic @Cleanup注解自动close。

@cleanup Mockedstatic<URLDecoder> urlDecoderMockedstatic =Mockito.mockstatic(URLDecoder.class);urlDecoderMockedstatic.when(()->URLDecoder.decode(Mockito.any(),Mockito.anystring())).thenReturn(JsoNutil.toJsonstr(depositTradeResp));

2. 工具类

使用mockConstruction

Mockito.mockConstruction(AesUtil.class, (util, context) -> {Mockito.when(util.decryptMsg(Mockito.anyString())).thenReturn(true);
});

3. 私有方法

使用反射机制

Method checkCouponByQuery = createGoOrderService.getClass().getDeclaredMethod("checkCouponByQuery", List.class, List.class, List.class);
checkCouponByQuery.setAccessible(true);try {checkCouponByQuery.invoke(createGoOrderService, addedXPlusOrderInfoList, usableCoupon, checkCouponResultList);
} catch (Exception e) {logger.info("异常信息:{}", e.getMessage());
}

4. 局部模拟

 ReflectUtil.setFieldValue(changeOrderService, "changeInfoMapper", changeInfoMapperOne);
BDDMockito.when(changeInfoMapperOne.getSubSegOrderList()).thenReturn(Arrays.asList("sdsd", "sds"));

三、单测类的实现

下面这个基类为Spring Boot应用程序的测试提供了一个基础框架,包括测试环境的配置、测试数据的加载、以及测试过程中所需的工具和资源的管理。这有助于确保测试的一致性、可重复性和可靠性。其中loadJsonParam 方法允许测试类从类路径下的文件中加载JSON数据,这在测试需要发送JSON请求的API时很有用。init 方法在每个测试方法之前初始化 MockMvc 对象,这是测试Spring MVC应用程序的关键步骤。after 方法可以用来执行测试后的清理工作。最后,getMockMvc 和 getParamJsonStr 方法提供了对 MockMvc 对象和JSON参数字符串的访问,以便在测试中使用。

package com.csair.ecs;import java.io.BufferedReader;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = GroupNeedServiceApplication.class)
@ActiveProfiles("test")
public class BaseTest {public static final String UTF_8 = "UTF-8";@Autowiredprivate WebApplicationContext webAppConfiguration;private MockMvc mockMvc;private String paramJsonStr;public void loadJsonParam(String classPathJsonFileName) {StringBuilder sb = new StringBuilder(300);try (BufferedInputStream inputStream = new BufferedInputStream(Thread.currentThread().getContextClassLoader().getResourceAsStream(classPathJsonFileName));BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, UTF_8))) {String temp;while ((temp = reader.readLine())!= null) {sb.append(temp);}} catch (IOException e) {e.printStackTrace();}this.paramJsonStr = sb.toString();}// 在每个测试方法执行之前,初始化MockMvc对象。@Beforepublic void init() {mockMvc = MockMvcBuilders.webAppContextSetup(webAppConfiguration).build();}// 在每个测试方法执行之后,可以执行清理工作。@Afterpublic void after() {}// 提供获取MockMvc对象的方法,以便在测试中使用。public MockMvc getMockMvc() {return mockMvc;}// 提供获取JSON参数字符串的方法,以便在测试中使用。public String getParamJsonStr() {return paramJsonStr;}
}

四、测试类实现

下面这个测试类通过继承 BaseTest 类,利用已经配置好的测试环境和工具。每个测试方法都设计来覆盖特定的功能点,确保服务在各种输入下都能正确执行。使用 Lombok 的 @Slf4j 注解简化了日志记录的配置,使得测试代码更加简洁。

@Slf4j
public class SystemParamsConfigServiceImplTest extends BaseTest {@Autowiredprivate SystemParamsConfigService systemParamsConfigService;@Testpublic void testSelectParamsPageList() {// Test case 1SystemParamsConfigReq req1 = new SystemParamsConfigReq();req1.getPage().setPageNo(1);req1.getPage().setPageSize(5);ResponseBase<PageData<SystemParamsConfig>> responseBase1 = systemParamsConfigService.selectParamsPageList(req1);log.info("结果:{}", JSONUtil.parseObj(responseBase1));// Test case 2SystemParamsConfigReq req2 = new SystemParamsConfigReq();req2.getPage().setPageNo(1);req2.getPage().setPageSize(5);req2.setParamKey("dd");ResponseBase<PageData<SystemParamsConfig>> responseBase2 = systemParamsConfigService.selectParamsPageList(req2);log.info("结果:{}", JSONUtil.parseObj(responseBase2));// Test case 3SystemParamsConfigReq req3 = new SystemParamsConfigReq();req3.getPage().setPageNo(1);req3.getPage().setPageSize(5);req3.setRemark("d");ResponseBase<PageData<SystemParamsConfig>> responseBase3 = systemParamsConfigService.selectParamsPageList(req3);log.info("结果:{}", JSONUtil.parseObj(responseBase3));}@Testpublic void testGetByParamKey() {ResponseBase<SystemParamsConfig> responseBase = systemParamsConfigService.getByParamKey("aa");log.info("结果:{}", JSONUtil.parseObj(responseBase));}@Testpublic void testInsertParamConfig() {SystemParamsConfig paramsConfig = new SystemParamsConfig();paramsConfig.setParamKey(RandomUtil.randomNumbers(6));paramsConfig.setParamValue("测试一下");paramsConfig.setOperator("wangjiansheng9");paramsConfig.setRemark("备注一下");// Test case 1ResponseBase<Integer> responseBase1 = systemParamsConfigService.insertParamConfig(paramsConfig);log.info("结果:{}", JSONUtil.parseObj(responseBase1));setParamKey(paramsConfig.getParamKey());// Test case 2paramsConfig.setParamKey("ferferfrefrefrefer");ResponseBase<Integer> responseBase2 = systemParamsConfigService.insertParamConfig(paramsConfig);log.info("结果:{}", JSONUtil.parseObj(responseBase2));}
}

五、IDEA查看覆盖率

在IntelliJ IDEA中,鼠标右键选中某个单元测试类或包,选择 更多运行/调试 - 使用覆盖率 - 使用覆盖率运行。

覆盖率

等待单元测试运行结束,会在IDEA右侧弹出覆盖率面板。在代码中查看具体覆盖情况。









本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/28904.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kubermetes 部署mysql pod

步骤 1: 创建 PersistentVolume 和 PersistentVolumeClaim 首先为 MySQL 创建一个 PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 来确保数据的持久性。 mysql-pv.yaml&#xff1a; apiVersion: v1 kind: PersistentVolume metadata:name: mysql-pv-volume spec:cap…

论坛社区基础版【项目测试报告】

文章目录 一、项目背景二、项目功能用户注册/登录帖子列表页发布帖子个人中心 三、测试工具和环境四、测试计划非功能测试用例功能测试用例部分人工手动测试截图web自动化测试测试用例代码框架 配置内容代码文件&#xff08;Utils.py&#xff09;注册页面代码文件&#xff08;R…

物联网IoT系列之MQTT协议基础知识

文章目录 物联网IoT系列之MQTT协议基础知识物联网IoT是什么&#xff1f;什么是MQTT&#xff1f;为什么说MQTT是适用于物联网的协议&#xff1f;MQTT工作原理核心组件核心机制 MQTT工作流程1. 建立连接2. 发布和订阅3. 消息确认4. 断开连接 MQTT工作流程图MQTT在物联网中的应用 …

如何面向DeepSeek编程,打造游戏开发工具集,提升工作效率

最近我在思考&#xff1a; 如何基于DeepSeek&#xff0c;来提升工作效率&#xff0c;构建高效游戏开发工作流。 方向有两个: A: 基于DeepSeek私有代码框架&#xff0c;让它完成项目代码的续写; B: 基于DeepSeek来创作一些工具&#xff0c;使用工具来提升效率&#xff0c;如…

云原生机密计算:构建基于可信执行环境的数据安全堡垒

引言&#xff1a;数据计算的最后一道防线 蚂蚁集团金融级机密计算平台承载日均20亿次敏感交易&#xff0c;密钥泄露风险降低99.97%。微软Azure DCsv3系列虚拟机实现SGX全内存加密性能损耗<15%&#xff0c;Google Anthos Confidential将跨云数据传输成本压缩45%。Gartner预测…

通用文件模型

一、通用文件模型 通常一个完整的Linux系统有数千到数百万个文件组成&#xff0c;文件中存储了程序、数据和各种信息。层次化的目录结构用于对文件进行编排和分组。 1.ReiserFS(新型的文件系统) -->Reiser4 它通过一种与众不同的方式----完全平衡树来容纳数据&#xff0c;包…

产品管理过程-思维导图

产品管理过程 1. 市场调研 与用户交流与直接面对客户的一线同事如销售、客服、技术支持等交流市场研究报告分析竞争对手分析用户数据分析 2. 需求管理 需求来源管理 市场需求内部需求运营需求战略需求其它需求 需求版本管理 需求分配管理 需求跟踪管理 3. 产品规划 市…

EtherNet/IP转Modbus解析基于网关模块的罗克韦尔PLC与Modbus上位机协议转换通讯案例

在工业自动化控制系统中&#xff0c;常常会遇到不同品牌和通信协议的设备需要协同工作的情况。本案例中&#xff0c;客户现场采用了 AB PLC&#xff0c;但需要控制的变频器仅支持 Modbus 协议。为了实现 AB PLC 对变频器的有效控制与监控&#xff0c;引入了捷米特 JM-EIP-RTU 网…

【进程和线程】(面试高频考点)

【进程和线程】 前言 在计算机编程领域&#xff0c;并发编程是一项至关重要的技术&#xff0c;而进程和线程正是实现并发编程的核心概念。为了让大家更直观地理解并发编程的作用&#xff0c;我们先来看一个简单的生活例子。 想象一下&#xff0c;现在有一大份美味的饭菜&…

HTML 编辑器推荐与 VS Code 使用教程

在进行 HTML 编程时&#xff0c;选择一款合适的 HTML 编辑器能极大地提高开发效率。以下为大家推荐几款常用且功能强大的 HTML 编辑器&#xff0c;同时详细介绍如何使用 VS Code 创建和预览 HTML 文件。 一、HTML 编辑器推荐 VS Code&#xff1a;由微软开发&#xff0c;是一款…

Kubernetes开发环境minikube | 开发部署apache tomcat web集群应用

minikube是一个主要用于开发与测试Kubernetes应用的运行环境&#xff0c;本文主要描述在minikube运行环境中部署J2EE tomcat web应用。 单节点Node多Pod实例部署 如上所示&#xff0c;在minikube运行的Linux部署环境中启动单节点Node 如上所示&#xff0c;在minikube的容器环境…

STM32---FreeRTOS中断管理试验

一、实验 实验目的&#xff1a;学会使用FreeRTOS的中断管理 创建两个定时器&#xff0c;一个优先级为4&#xff0c;另一个优先级为6&#xff1b;注意&#xff1a;系统所管理的优先级范围 &#xff1a;5~15 现象&#xff1a;两个定时器每1s&#xff0c;打印一段字符串&#x…

永磁直驱式风力发电虚拟同步机仿真模型Matlab/Simulink模型

很久没有分享虚拟同步机控制相关的方向了&#xff0c;毕业后在电科院的项目又有所接触。这个课题方向其实作为硕士毕业课题还是够用的&#xff0c;相对来说也是比较容易毕业的&#xff0c;因为涉及的分支比较多。 后续对虚拟同步机的控制&#xff0c;我就延续我前面博客提到的方…

图像分类项目1:基于卷积神经网络的动物图像分类

1、选题背景及动机 在现代社会中&#xff0c;图像分类是计算机视觉领域的一个重要任务。动物图像分类具有广泛的应用&#xff0c;例如生态学研究、动物保护、农业监测等。通过对动物图像进行自动分类&#xff0c;可以帮助人们更好地了解动物种类、数量和分布情况&#xff0c;从…

Vue 3 整合 WangEditor 富文本编辑器:从基础到高级实践

本文将详细介绍如何在 Vue 3 项目中集成 WangEditor 富文本编辑器&#xff0c;实现图文混排、自定义扩展等高阶功能。 一、为什么选择 WangEditor&#xff1f; 作为国内流行的开源富文本编辑器&#xff0c;WangEditor 具有以下优势&#xff1a; 轻量高效&#xff1a;压缩后仅…

Ansys Zemax | 使用衍射光学器件模拟增强现实 (AR) 系统的出瞳扩展器 (EPE):第 4 部分

附件下载 联系工作人员获取附件 在 OpticStudio 中使用 RCWA 工具为增强现实&#xff08;AR&#xff09;系统设置出瞳扩展器&#xff08;EPE&#xff09;的示例中&#xff0c;首先解释了k空间中光栅的规划&#xff0c;并详细讨论了设置每个光栅的步骤。 介绍 本文是该四篇文…

CMake学习笔记(一):工程的新建和如何将源文件生成二进制文件

cmake是我们在工作过程中比较常见的一个工具&#xff0c;该系列文章是自己用来学习的笔记。目前只是记录下自己学习cmake的过程中的一些重要的知识点&#xff0c;其是以项目需求为导向并非完整的cmake的学习路线和系统&#xff0c;同样也并非适合所有的人。 1.生成一个可执行文…

libcoap在Ubuntu下的编译(基于CMake)

引言 libcoap 是一个开源的轻量级 C 语言库&#xff0c;用于实现 CoAP&#xff08;Constrained Application Protocol&#xff0c;受限应用协议&#xff09;。CoAP 是一种专为资源受限设备设计的轻量级通信协议&#xff0c;适用于物联网&#xff08;IoT&#xff09;和嵌入式系…

Docker新手入门(持续更新中)

一、定义 快速构建、运行、管理应用的工具。 Docker可以帮助我们下载应用镜像&#xff0c;创建并运行镜像的容器&#xff0c;从而快速部署应用。 所谓镜像&#xff0c;就是将应用所需的函数库、依赖、配置等应用一起打包得到的。 所谓容器&#xff0c;为每个镜像的应用进程创建…

蓝桥杯C组真题——巧克力

题目如下 思路 代码及解析如下 谢谢观看