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 转载请注明来源

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Java 配置 HTTP/Socks 代理竟能如此简单
在网络请求过程中,使用代理是一种常见的需求。代理服务器可以帮助我们隐藏真实的 IP 地址、加速访问速度、访问公司特定内网等等要求。在 Java 中,我们可以通过一些库或框架来实现代理的设置和使用。 但如果使用 OkHttp、HttpClient 亦或是 Retrofit 和 Feign,需要实现 Socks 协议代理都需要实现SSLSocketFactory类或ConnectionSocketFactory接口的子类,重写createSokcet方法,实现起来非常的麻烦。如果代理还需要用户名密码验证(大部分都会有),还需要实现Authenticator的子类,并通过ThreadLocal分配到请求各自的线程中,整个过程需要自己写很多代码,无比烦人。 而本文将介绍如何使用一种最简单的方法,即使用声明式 HTTP 框架 Forest,结合@HTTPProxy 和 @SocksProxy注解来发送 HTTP/HTTPS 请求,来快速实现代理功能。 Forest 的基本使用 添加 Forest 依赖 <dependency> <groupId>com.dtflys.f...
- 下一篇
突破时空之限,智能远程监考方案助力编程等级考试
用指尖,「敲」下一段天马行空的想象。 7月底,2023青少年人工智能编程水平测试(YCL)如期开展,10万+考生完成线上应考。 作为“青少年信息技术培养工程”的重点项目之一,青少年人工智能编程水平测试,由工业和信息化部教育与考试中心、中国电子教育学会、中国工信出版传媒集团——北京信通有限责任公司共同发起,以信息技术等级考试的形式,对学生的多学科综合知识掌握、创造性思维、编程运用能力等方面进行测评,并为青少年提供相应能力证明。 YCL考试体系分为1-8级,采用“统一在线考试”的形式,考生需自行准备场地及电脑等设备,并在指定时间内通过网络进行在线考试,而监考老师也分布在全国各地,只需同步线上监考而不受时空之限。 在这超大规模远程考试的背后,是信通传媒联合阿里云视频云,基于智能远程监考PaaS+解决方案打造的新版在线考试系统。 16场考试,10万+流量并发 组织大规模线上考试实属不易。 信通传媒在开展青少年编程等级考试的过程中,也遭遇显著的痛点: ➤ 规模大,系统并发要求高。 本次编程考试为期两天,共组织16场考试,单场最高并发超过2万,两天共累计10万+推流,如此大的流量压力对远程监考方案...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- Mario游戏-低调大师作品
- CentOS7安装Docker,走上虚拟化容器引擎之路