Java 单元测试及常用语句 | 京东物流技术团队
1 前言
编写 Java 单元测试用例,即把一段复杂的代码拆解成一系列简单的单元测试用例,并且无需启动服务,在短时间内测试代码中的处理逻辑。写好 Java 单元测试用例,其实就是把“复杂问题简单化,建单问题深入化“。在编写的过程中, 我们也可以对自己的代码进行一个二次检查。
以下是我总结的一些编写单元测试的好处:
1.测试代码逻辑时,不需要启动整个应用。
2.单元测试可以覆盖边界值
3.提高原有代码的复用
4.可以有效避免代码改动后,对原有逻辑的潜在影响
2 准备环境
Mockito 是目前最普遍的单元测试模拟框架。Mockito 可以模拟应用中依赖的复杂对象,从而把测试对象和依赖对象隔离开。PowerMock 为 Mockito 提供了扩展功能。为模拟静态方法,final 类,和私有方法等。我们选择使用以 Mockito 为主,PowerMock 为辅的框架来做单元测试。
2.1 引入 Mockito 和 PowerMock 包,在 pom.xml 文件中加入以下依赖:
PowerMock 目前最新版本为 2.0.9【PowerMock链接】由于 PowerMock 包中已经包含了对应的 Mockito 和 JUnit 包,所以无需再单独引入。
3 一些常用的 mock 语句
3.1 模拟指定类的对象实例,用于模拟依赖对象(类成员)
在 Spring 中,这些成员对象通过 @Autowire,@Resource,@Value 等方式注入,可能涉及到环境配置或者依赖第三方接口。在单元测试中,不是我们关注的点,所以可以用 mock 模拟
3.2 定义被测试对象
把被测试服务类进行实例化
3.3 模拟枚举类型/静态方法
需要把对应的模拟类放在 @PrepareForTest 中
3.4 模拟依赖方法
在模拟完依赖的参数和返回值后,可以利用 Mockito 功能,进行依赖方法的模拟。如果模拟对象还有方法调用,则需要模拟这些依赖对象的方法。
3.5 模拟构造方法
PowerMock 提供了对构造方法的模拟,但是需要把构造方法的类放在 @PrepareForTest 中
3.6 验证方法调用次数
被测方法调用后,一些方法会出现调用多次或根据不同条件进行不同次数的调用。此时,可以根据验证方法调用次数,确定代码的有效性
3.7 验证返回值
对于方法调用后的出参,我们会有一定的预期。所以,可以根据校验返回值是否符合预期,确保返回值的正确性
3.8 验证异常对象
JUnit 的 @Test 注解提供了一个 expected 属性,可以指定一个期望的异常类型,用于捕获异常并验证其异常类型。【注】:只能验证异常类型,不能验证异常信息。
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 转载请注明来源
版权声明: 本文为 InfoQ 作者【京东科技开发者】的原创文章。
原文链接:【http://xie.infoq.cn/article/6ef616f1d22fa3f6ab8dd8024】。文章转载请联系作者。
评论