当前位置: 首页 > news >正文

Java单元测试及常用语句 | 京东物流技术团队

1 前言

编写Java单元测试用例,即把一段复杂的代码拆解成一系列简单的单元测试用例,并且无需启动服务,在短时间内测试代码中的处理逻辑。写好Java单元测试用例,其实就是把“复杂问题简单化,建单问题深入化“。在编写的过程中, 我们也可以对自己的代码进行一个二次检查。

以下是我总结的一些编写单元测试的好处:

1.测试代码逻辑时,不需要启动整个应用。

2.单元测试可以覆盖边界值

3.提高原有代码的复用

4.可以有效避免代码改动后,对原有逻辑的潜在影响

2 准备环境

Mockito是目前最普遍的单元测试模拟框架。Mockito可以模拟应用中依赖的复杂对象,从而把测试对象和依赖对象隔离开。PowerMock为Mockito提供了扩展功能。为模拟静态方法,final类,和私有方法等。我们选择使用以Mockito为主,PowerMock为辅的框架来做单元测试。

2.1 引入Mockito和PowerMock包,在pom.xml文件中加入以下依赖:

<properties><powermock.version>2.0.9</powermock.version>
</properties>
<dependency><groupId>org.powermock</groupId><artifactId>powermock-core</artifactId><version>${powermock.version}</version><scope>test</scope>
</dependency>
<dependency><groupId>org.powermock</groupId><artifactId>powermock-api-mockito2</artifactId><version>${powermock.version}</version><scope>test</scope>
</dependency>
<dependency><groupId>org.powermock</groupId><artifactId>powermock-module-junit4</artifactId><version>${powermock.version}</version><scope>test</scope>

PowerMock目前最新版本为2.0.9【PowerMock链接】由于PowerMock包中已经包含了对应的Mockito和JUnit包,所以无需再单独引入。

3 一些常用的mock语句

3.1 模拟指定类的对象实例,用于模拟依赖对象(类成员)

在Spring中,这些成员对象通过@Autowire,@Resource,@Value等方式注入,可能涉及到环境配置或者依赖第三方接口。在单元测试中,不是我们关注的点,所以可以用mock模拟

//方法一
Mockito.mock(OrderInfo.class);
//方法二
@Mock
private OrderInfo orderInfo;@Before
public void setUp(){
MockitoAnnotations.initMocks(this);
}

3.2 定义被测试对象

把被测试服务类进行实例化

@InjectMocks
private OrderServiceImpl orderService;

3.3 模拟枚举类型/静态方法

需要把对应的模拟类放在@PrepareForTest中

//必须添加@RunWith和@PrepareForTest在类前
@RunWith(PowerMockRunner.class)
@PrepareForTest(OrderTypeEnum.class)//在@Before中添加枚举mock
@Before
public void beforeTest() {mockStatic(OrderTypeEnum.class);
}

3.4 模拟依赖方法

在模拟完依赖的参数和返回值后,可以利用Mockito功能,进行依赖方法的模拟。如果模拟对象还有方法调用,则需要模拟这些依赖对象的方法。

/***
when.thenReturn 和 doReturn.when是两种实现方式
只有在使用@Spy时才会有区别
参考链接:https://www.imooc.com/wenda/detail/594190#id_653606
***///模拟枚举的方法调用
when(OrderTypeEnum.getByValue(anyInt())).thenReturn(100);
//模拟依赖对象的依赖方法调用
doReturn(resultInfoDTO).when(orderInfoService).getLastOrderInfo(orderInfoDTO);

3.5 模拟构造方法

PowerMock提供了对构造方法的模拟,但是需要把构造方法的类放在@PrepareForTest中

//必须在@PrepareForTest中添加对应类
@PrepareForTest({OrderTypeEnum.class, OrderServiceImpl.class})
whenNew(OrderInfoDTO.class).withNoArguments().thenReturn(orderInfoDTO);

3.6 验证方法调用次数

被测方法调用后,一些方法会出现调用多次或根据不同条件进行不同次数的调用。此时,可以根据验证方法调用次数,确定代码的有效性

verify(orderInfoService,times(1)).getLastOrderInfo(orderInfoDTO);

3.7 验证返回值

对于方法调用后的出参,我们会有一定的预期。所以,可以根据校验返回值是否符合预期,确保返回值的正确性

Assert.assertEquals(result, "123");

3.8 验证异常对象

JUnit的@Test注解提供了一个expected属性,可以指定一个期望的异常类型,用于捕获异常并验证其异常类型。【注】:只能验证异常类型,不能验证异常信息。

@Test(expected = BPLException.class)

4 单测举例

下面是一个本地方法的单元测试用例,方法中调用了外部接口,并且其中包含了枚举值的使用。

源方法即需要单测方法:

首先,是单元测试时一些必要的初始化

4.1 单测场景一(确定接口调用,并返回值正确):

通过verify方法来确定接口是否调用过,并且只调用过1次。

通过assert来确认返回值是否满足预期

4.2 单测场景二(必要异常是否抛出):

通过在@Test注解上加入expected属性,测试当接口返回值为空时,是否可以抛出异常

4 总结

编写单元测试在开发中的地位举足轻重。在开发过程中,避免不了优化或重构历史代码。单元测试,在一定程度上可以帮助测试更新后逻辑,以及潜在调用链。另外也分享一些链接,希望可以帮助大家完成从0到1的搭建。

5 参考资料

  • Java编程技巧之单元测试用例编写流程:https://mp.weixin.qq.com/s/hX_RIYs-nBnqVwdq5B4rhg
  • powerMock的Git链接:https://github.com/powermock/powermock
  • powerMock简介:https://www.baeldung.com/intro-to-powermock
  • 避免Install的时候Skip test: https://maven.apache.org/plugins-archives/maven-surefire-plugin-2.12.4/examples/skipping-test.html

作者:京东物流 牟佳义

来源:京东云开发者社区 自猿其说Tech 转载请注明来源

相关文章:

Java单元测试及常用语句 | 京东物流技术团队

1 前言 编写Java单元测试用例&#xff0c;即把一段复杂的代码拆解成一系列简单的单元测试用例&#xff0c;并且无需启动服务&#xff0c;在短时间内测试代码中的处理逻辑。写好Java单元测试用例&#xff0c;其实就是把“复杂问题简单化&#xff0c;建单问题深入化“。在编写的…...

详解Vue中的render: h => h(App)

声明:只是记录&#xff0c;会有错误&#xff0c;谨慎阅读 我们用脚手架初始化工程的时候&#xff0c;main.js的代码如下 import Vue from vue import App from ./App.vueVue.config.productionTip falsenew Vue({// 把app组件放入容器中render: h > h(App), }).$mount(#ap…...

归并排序的详解!

本文旨在讲解归并排序的实现&#xff08;递归及非递归&#xff09;搬好小板凳&#xff0c;干货来了&#xff01; 前序&#xff1a; 在介绍归并排序之前&#xff0c;需要给大家介绍的是什么是归并&#xff0c;归并操作&#xff0c;也叫归并算法&#xff0c;指的是将两个顺序序列…...

排盘程序算法探寻举例(陆先生八字)

算法实现&#xff1a; 1.庚生未月&#xff0c;燥土不能生金&#xff0c;日支申金为日主墙根&#xff0c;月干辛金比劫透出傍身&#xff0c;月干强。年干甲木自做寅木强根&#xff0c;又得月支乙木中气&#xff0c;甲木强旺有力&#xff0c;时干丙火七杀得未土余气&#xff0c;…...

考研408 | 【操作系统】终章

I/O设备的基本概念和分类 I/O设备&#xff1a; I/O设备的分类 1.按使用特性&#xff1a; 2.按传输速率分类&#xff1a; 3.按信息交换的单位分类&#xff1a; 总结&#xff1a; I/O控制器 I/O设备的机械部件&#xff1a; I/O设备的电子部件&#xff08;I/O控制器&#…...

亚马逊云科技生成式AI技术辅助教学领域,近实时智能应答2D数字人搭建

早在大语言模型如GPT-3.5等的兴起和被日渐广泛的采用之前&#xff0c;教育行业已经在AI辅助教学领域有过各种各样的尝试。在教育行业&#xff0c;人工智能技术的采用帮助教育行业更好地实现教学目标&#xff0c;提高教学质量、学习效率、学习体验、学习成果。例如&#xff0c;人…...

Programming abstractions in C阅读笔记:p139-p143

《Programming Abstractions In C》学习第55天&#xff0c;p139-p140&#xff0c;总结如下&#xff1a; 一、技术总结 1.文件I/O操作 文件I/O操作可以分为一下这些步骤&#xff1a; (1)声明文件指针对象。 File *infile;(2)打开文件 fopen()。打开文件的模式有“r”, “w…...

MyBatis-Plus学习笔记

1.MyBatis-Plus简介&#xff1a; MyBatis-Plus是一个MyBatis的增强工具&#xff0c;在MyBatis的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。MyBatis-Plus提供了通用的mapper和service&#xff0c;可以在不编写任何SQL语句的情况下&#xff0c;快速的实现对单…...

linux安装docker全过程

3. 第二步&#xff1a;设置docker的存储库。就两条命令&#xff0c;我们直接执行就好。 ​ sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo ​​ 4. 安装docker engine和docker-compose。 执行命…...

Spring 中存取 Bean 的相关注解

目录 一、五大类注解 1、五大类注解存储Bean对象 1.1Controller(控制器储存) 1.2Service(服务存储) 1.3Repository(仓库存储) 1.4Component(组件存储) 1.5Configuration(配置存储) 2、五大类注解小结 2.1为什么要这么多类注解 2.2 五大类注解之间的关系 二、方法注解 1.方法注…...

Camunda 7.x 系列【38】表单服务 FormService

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 概述2. 演示2.1 获取流程开始表单2.2 启动流程2.3 查询任务表单2.4 完成任务3. 实际开发…...

保姆级教程之SABO-VMD-SVM的西储大学轴承诊断

之前写过一篇优化核极限学习机的轴承诊断&#xff0c;今天再出一期基于SVM的轴承诊断。 依旧是包含了从数据处理&#xff0c;到减法优化器SABO算法优化VMD参数&#xff0c;再到支持向量机的故障诊断&#xff0c;实现故障诊断的全流程&#xff0c;其他类型的故障诊断均可参考此流…...

指向任意节点的带环链表

&#x1f308;图示指向任意节点的带环链表 如图&#xff1a; &#x1f308;快慢指针法判断链表是否带环 &#x1f31f;思路&#xff1a;快指针fast一次走2步&#xff0c;慢指针slow一次走1步&#xff0c;fast先进环在换中运动&#xff0c;随后slow进入环。两指针每同时移动…...

应用于伺服电机控制、 编码器仿真、 电动助力转向、发电机、 汽车运动检测与控制的旋变数字转换器MS5905P

MS5905P 是一款 12bit 分辨率的旋变数字转换器。 片上集成正弦波激励电路&#xff0c;正弦和余弦允许输入峰峰值 幅度为 2.3V 到 4.0V &#xff0c;可编程激励频率为 10kHz 、 12kHz 、 15kHz 、 20kHz 。 转换器可并行或串行输出角度 和速度对应的数字量。 MS5905…...

Ansible学习笔记(持续更新)

Ansible学习目录 1.自动化运维1.1 企业实际应用场景1.1.1 Dev开发环境1.1.2 测试环境1.1.3 发布环境1.1.4 生产环境1.1.5 灰度环境 1.2 程序发布1.3 自动化运维应用场景1.4 常用自动化运维工具 2.Ansible介绍和架构2.1 Ansible特性2.2 Ansible架构2.2.1 Ansible主要组成部分2.2…...

CCF HPC China2023|澎峰科技:使能先进计算,赋能行业应用

CCF HPC China2023圆满落幕&#xff01; 桂秋八月&#xff0c;为期三天的中国高性能计算领域最高规格盛会——2023CCF全球高性能计算学术年会&#xff08;HPC China&#xff09;在青岛红岛国际展览中心圆满落幕。行业超算大咖、顶级学界精英、先锋企业领袖参会者齐聚山东青岛&a…...

【FlowDroid】一、处理流程学习

FlowDroid 一、处理流程学习 下载配置源码概况代码逻辑分析analyzeAPKFilerunInfoflowprocessEntryPointcalculateCallbacks(sourcesAndSinks)再次回到processEntryPoint 自己做一些笔记 下载配置 参照我前面的文章可以使用FlowDroid安装初体验 为了看代码了解FlowDroid如何处…...

MyBatis——MyBatis插件原理

摘要 本博文主要介绍MyBatis插件机原理&#xff0c;帮助大家更好的理解和学习MyBatis。 一、插件机制概述 MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下&#xff0c;MyBatis允许使用插件来拦截的方法调用包括&#xff1a; Executor (update, que…...

简易虚拟培训系统-UI控件的应用5

目录 Toggle控件简介 示例-使用Toggle组实现主轴速度选择 本篇介绍UI控件Toggle&#xff0c;尝试一个小示例-使用单选框实现速度的选择控制。 Toggle控件简介 1. Toggle的结构如下&#xff1a;最重要的Toggle组件挂在Toggle节点上&#xff0c;下面的Image组件用于显示单选框…...

Lnmp架构

关闭防火墙 安装依赖包 yum -y install pcre-devel zlib-devel gcc gcc-c make 创建运行用户、组 编译安装Nginx 让系统识别nginx的操作命令 添加Nginx系统服务 vim /lib/systemd/system/nginx.service 编译安装mysql 安装Mysql环境依赖包 创建运行用户 编译安装 cd /opt …...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...