《Java单元测试实战》——编写方法:Java编程技巧之单元测试用例编写流程(16)

简介: 《Java单元测试实战》——编写方法:Java编程技巧之单元测试用例编写流程(16)

《Java单元测试实战》——编写方法:Java编程技巧之单元测试用例编写流程(15) https://developer.aliyun.com/article/1232403?groupCode=java



十一、 典型案例及解决方案

 

这里,只收集了几个经典案例,解决了特定环境下的特定问题。

 

1. 测试框架特性导致问题

 

在编写单元测试用例时,或多或少会遇到一些问题,大多数是由于对测试框架特性不熟悉导致,比如:

 

Mockito不支持对静态方法、构造方法、final方法、私有方法的模拟;

 

Mockito的any相关的参数匹配方法并不支持可空参数和空参数;

 

采用Mockito的参数匹配方法时,其它参数不能直接用常量或变量,必须使用Mockito的eq方法;

 

使用when-then语句模拟Spy对象方法会先执行真实方法,应该使用do-when语句;

 

PowerMock对静态方法、构造方法、final方法、私有方法的模拟需要把对应的类添加到@PrepareForTest注解中;

 

PowerMock模拟JDK的静态方法、构造方法、final方法、私有方法时,需要把使用这些方法的类加入到@PrepareForTest注解中,从而导致单元测试覆盖率不被统计;

 

PowerMock使用自定义的类加载器来加载类,可能导致系统类加载器认为有类型转换问题;需要加上@PowerMockIgnore({"javax.crypto.*"})注解,来告诉PowerMock这个包不要用PowerMock的类加载器加载,需要采用系统类加载器来加载。

 

对于这些问题,可以根据提示信息查阅相关资料解决,这里就不再累述了。

 

2. 捕获参数值已变更问题

 

在编写单元测试用例时,通常采用ArgumentCaptor进行参数捕获,然后对参数对象值进行验证。如果参数对象值没有变更,这个步骤就没有任何问题。但是,如果参数对象值在后续流程中发生变更,就会导致验证参数值失败。

 

 

原始代码:


image.png


测试用例:

image.png


问题现象:

 

执行单元测试用例失败,抛出以下异常信息:

image.png

问题原因:

 

由于参数dataList在调用dataStorage.test方法后,都被主动调用dataList.clear方法进行清空。由于ArgumentCaptor捕获的是对象引用,所以最后捕获到了同一个空列表。

 

解决方案:

 

可以在模拟依赖方法dataStorage.test时,保存传入参数的当前值进行验证。代码如下:

image.png


3. 模拟Lombok的log对象问题

 

Lombok的@Slf4j注解,广泛地应用于Java项目中。在某些代码分支里,可能只有log记录日志的操作,为了验证这个分支逻辑被正确执行,需要在单元测试用例中对log记录日志的操作进行验证。

 

原始方法:

image.png

测试用例:

image.png


问题现象:

 

执行单元测试用例失败,抛出以下异常信息:

image.png

原因分析:

 

经过调式跟踪,发现ExampleService中的log对象并没有被注入。通过编译发现,Lombok的@Slf4j注解在ExampleService类中生成了一个静态常量log,而@InjectMocks注解并不支持静态常量的注入。

 

解决方案:

 

采用作者实现的FieldHelper.setStaticFinalField方法,可以实现对静态常量的注入模拟对象。

image.png



《Java单元测试实战》——编写方法:Java编程技巧之单元测试用例编写流程(17 https://developer.aliyun.com/article/1232401?groupCode=java

相关文章
|
26天前
|
消息中间件 Java Kafka
在Java中实现分布式事务的常用框架和方法
总之,选择合适的分布式事务框架和方法需要综合考虑业务需求、性能、复杂度等因素。不同的框架和方法都有其特点和适用场景,需要根据具体情况进行评估和选择。同时,随着技术的不断发展,分布式事务的解决方案也在不断更新和完善,以更好地满足业务的需求。你还可以进一步深入研究和了解这些框架和方法,以便在实际应用中更好地实现分布式事务管理。
|
25天前
|
安全 Java 开发者
Java中WAIT和NOTIFY方法必须在同步块中调用的原因
在Java多线程编程中,`wait()`和`notify()`方法是实现线程间协作的关键。这两个方法必须在同步块或同步方法中调用,这一要求背后有着深刻的原因。本文将深入探讨为什么`wait()`和`notify()`方法必须在同步块中调用,以及这一机制如何确保线程安全和避免死锁。
37 4
|
25天前
|
Java
深入探讨Java中的中断机制:INTERRUPTED和ISINTERRUPTED方法详解
在Java多线程编程中,中断机制是协调线程行为的重要手段。了解和正确使用中断机制对于编写高效、可靠的并发程序至关重要。本文将深入探讨Java中的`Thread.interrupted()`和`Thread.isInterrupted()`方法的区别及其应用场景。
25 4
|
23天前
|
Java 数据处理 数据安全/隐私保护
Java处理数据接口方法
Java处理数据接口方法
25 1
|
XML JSON 前端开发
阿里云JAVA高级测试试题及答案(十二)
阿里云JAVA高级测试试题及答案
245 0
阿里云JAVA高级测试试题及答案(十一)
阿里云JAVA高级测试试题及答案
214 0
|
XML 缓存 druid
阿里云JAVA高级测试试题及答案(十)
阿里云JAVA高级测试试题及答案
249 0
|
XML 缓存 前端开发
阿里云JAVA高级测试试题及答案(九)
阿里云JAVA高级测试试题及答案
150 0
|
XML 前端开发 JavaScript
阿里云JAVA高级测试试题及答案(八)
阿里云JAVA高级测试试题及答案(八)
302 0
|
缓存 算法 前端开发
阿里云JAVA高级测试试题及答案(七)
阿里云JAVA高级测试试题及答案(七)
186 0
下一篇
DataWorks