java 单元测试学习

embedded/2024/10/21 9:45:40/

单测的标准:

语句覆盖率达到70%;核心模块的语句覆盖率和分支覆盖率都要达到100%。 — 《阿里巴巴Java开发手册》
单测覆盖度分级参考
Level1:正常流程可用,即一个函数在输入正确的参数时,会有正确的输出
Level2:异常流程可抛出逻辑异常,即输入参数有误时,不能抛出系统异常,而是用自己定义的逻辑异常通知上层调用代码其错误之处
Level3:极端情况和边界数据可用,对输入参数的边界情况也要单独测试,确保输出是正确有效的
Level4:所有分支、循环的逻辑走通,不能有任何流程是测试不到的
Level5:输出数据的所有字段验证,对有复杂数据结构的输出,确保每个字段都是正确的

60%左右的单测覆盖率可以非常轻松达到,但达到95%以上的覆盖率,需要覆盖各种代码分支和异常情况等,甚至是配置和bean的初始化方法,所投入的时间非常巨大,但边际效应递减。我想测试toString, getter/setter这样的方法也没有意义。多少合适,我认为没有一个固定的标准。高代码覆盖率百分比不表示成功,也不意味着高代码质量。该舍弃测试的部分就大胆的ignore掉。

1、隐藏的测试边界值
2、不要在springboot测试中使用@Transactional以及操作真实数据库
3、单测里时间相关的内容

笔者曾经在工作中遇到过一个极端case,一个CI平时都正常运行,有一次深夜发布, CI跑不过,后来经过第二天check才发现有前人在单测中取了当前时间,在业务逻辑中含有夜间逻辑(夜间消息不发),导致了CI无法通过。那么时间在单测中要如何处理呢?

在使用Mockito时,可以使用mock(Date.class)来模拟日期对象,然后使用when(date.getTime()).thenReturn(time)来设置日期对象的时间。

如果你使用了calendar.getInstance(),如何获取当前时间?Calendar.getInstance()是static方法,无法通过Mockito进行mock。需要引入powerMock,或者升级到mockito 4.x才能支持:

final类,static类等的单元测试

如第3点提到的calendar的例子,static类的mock需要mockito4.x的版本。否则就要引入powermock,powermock不兼容mockito3.x版本,不兼容mockito 4.x版本。由于老的应用引入了非常多的mockito3.x的版本,直接使用mockito4.x对final和static类进行mock需要排包。实践中看,JUnit、Mockito、Powermock三者之间的版本号有兼容性问题,可能会出现java.lang.NoSuchMethodError,需要根据实际的情况选择版本进行mock。

但是在新项目立项的时候,要确定好使用的mockito和junit版本,是否引入powermock等框架,确保环境稳定可用。老项目建议不要大规模改动mockito和powermock的版本,容易排包排到怀疑人生。
总结一下什么时候使用容器:

// 1. 使用PowerMockRunner
@RunWith(PowerMockRunner.class)

// 2.使用PandoraBootRunner, 启动pandora,使用tair,metaq等
@RunWith(PandoraBootRunner.class)

// 3. springboot启动,加入context上下文,可以直接获取bean
@SpringBootTest(classes = {TestApplication.class})

不要为了覆盖率测没意义的代码

比如toString,比如getter,setter,都是机器生成的代码,单测没意义。如果是为了整体测试覆盖率的提高,那么请在CI中排掉这部分包:

如何测试void方法

如果void方法内部造成了数据库的变更,比如insertPlan(Plan plan),并通过H2操作过数据库,那么可以验证数据库的条数变化等,校验void方法的正确性。
如果void方法调用了函数,可以通过verify验证方法得到调用次数:
userService.updateName(1L,“qiushuo”);
verify(mockedUserRepository, times(1)).updateName(1L,“qiushuo”);
如果void方法可能会造成抛出异常。
可以通过dothrow来 mock方法抛出的异常:

@Test(expected = InvalidParamException.class)
public void testUpdateNameThrowExceptionWhenIdNull() {
doThrow(new InvalidParamException())
.when(mockedUserRepository).updateName(null,anyString();
userService.updateName(null,“qiushuo”);
}

使用 squaretest testme junit5 + Mockito

IDEA 安装 squaretest testme 插件

配置模板后 在你想要的生的单测的类 右键生成 test类


http://www.ppmy.cn/embedded/94627.html

相关文章

解决element-ui回车键绑定按钮功能后却刷新浏览器的问题

最近写代码时,遇到要给回车键绑定确定的功能,并且打开对话框时要自动获取输入框焦点,发现一但重新打开浏览器,第一次执行回车键的功能时就会刷新浏览器,后续则会成功执行。但是一但再一次重新打开浏览器,还…

onvif技术框架介绍

我们在学习任何一个新的技术点之前,都要从整体框架再到细节,在开始学习的时候,不用去扣细节,而是从整个架构出发;所有学习onvif客户端开发,也是一样的,我们先从整体框架开发: 在讲解…

[windows][vscode]正则表达式匹配文件中所有空白行

在Visual Studio Code (VSCode) 中,^\s*(?\r?$)\n 这个正则表达式模式用于匹配文件中所有空白行,包括空行和只包含空白字符(如空格、制表符等)的行。下面是对这个正则表达式的解释: ^:匹配行的开始。\s*…

FPGA入门:二选一多路选择器

FPGA入门学习第一例:二选一多路选择器 设计需求 设计一个二选一多路选择器模块,包含三个输入信号(a/b/sl),一个输出信号(out)。 当sl 1时,out a;当sl 0时&#xff0…

【Linux SQLite数据库】一、SQLite交叉编译与移植

SQLite 是一个用 C 语言编写的开源、轻量级、快速、独立且高可靠性的 SQL 数据库引擎,它提供了功能齐全的数据库解决方案。SQLite 几乎可以在所有的手机和计算机上运行,它被嵌入到无数人每天都在使用的众多应用程序中。此外,SQLite 还具有稳定…

jenkins一键推送到远程服务器并用docker容器启动

1.安装jenkins 我后端使用的是宝塔面板来安装的容器化jenkins,要选中允许外部访问,安装完之后没有那个选项了,一开始安装的时候要选中不使用域名和后面的允许外部访问。Jenkins 版本为: 2.462.1 2.配置Jenkins 2.1 Git plugin 安装完毕之…

SpringCloud 微服务nacos和eureka

Spring是微服务架构,是一种经过良好架构设计的分布式架构方案。 微服务架构有如下特性 单一:微服务拆分粒度小,每一个服务都对应唯一的业务能力,做到单一职责,避免重复业务开发 面向服务:微服务对外暴漏…

CC攻击解决方案,如何处理CC攻击

在数字化时代,网站作为企业与用户交流的重要窗口,其安全性和稳定性至关重要。然而,CC攻击(Challenge Collapsar Attack)这一网络威胁如同网络世界中的“洪水猛兽”,时刻威胁着网站的正常运行。今天我们就来…