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

1 前言

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

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

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

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

3.提高原有代码的复用

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

2 准备环境

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

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

1<properties> 2 <powermock.version>2.0.9</powermock.version> 3</properties> 4<dependency> 5 <groupId>org.powermock</groupId> 6 <artifactId>powermock-core</artifactId> 7 <version>${powermock.version}</version> 8 <scope>test</scope> 9</dependency> 10<dependency> 11 <groupId>org.powermock</groupId> 12 <artifactId>powermock-api-mockito2</artifactId> 13 <version>${powermock.version}</version> 14 <scope>test</scope> 15</dependency> 16<dependency> 17 <groupId>org.powermock</groupId> 18 <artifactId>powermock-module-junit4</artifactId> 19 <version>${powermock.version}</version> 20 <scope>test</scope> 21

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

3 一些常用的mock语句

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

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

1//方法一 2Mockito.mock(OrderInfo.class); 3//方法二 4@Mock 5private OrderInfo orderInfo; 6 7 8@Before 9public void setUp(){ 10MockitoAnnotations.initMocks(this); 11} 12

3.2 定义被测试对象

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

1@InjectMocks 2private OrderServiceImpl orderService; 3

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

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

1//必须添加@RunWith和@PrepareForTest在类前 2@RunWith(PowerMockRunner.class) 3@PrepareForTest(OrderTypeEnum.class) 4 5 6//在@Before中添加枚举mock 7@Before 8public void beforeTest() { 9 mockStatic(OrderTypeEnum.class); 10} 11

3.4 模拟依赖方法

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

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

3.5 模拟构造方法

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

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

3.6 验证方法调用次数

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

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

3.7 验证返回值

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

1Assert.assertEquals(result, "123"); 2

3.8 验证异常对象

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

1@Test(expected = BPLException.class) 2

4 单测举例

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

源方法即需要单测方法:

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

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

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

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

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

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

4 总结

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

5 参考资料

作者:京东物流 牟佳义

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

点赞
收藏

评论区

加载中...

相关推荐

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

java单元测试

Java单元测试1.概述java单元测试是最小的功能单元测试代码,单元测试就是针对单个java方法的测试。java程序的最小功能单元是方法。main方法进行测试的缺点:只能有一个main()方法,不能把测试代码分离出来无法打印出测试结果和期望结果.例如:expected:

java单元测试工具

前言随着DevOp的不断流行,自动化测试慢慢成为Java开发者的关注点。因此,本文将分享10款优秀的单元测试框架和库,它们可以帮助Java开发人员在其Java项目上编写单元测试和集成测试。1\.JUnit我绝对JUnit不需要太多的介绍了。即使您是Java初学者,也可能听说过它。它可以帮助您为Java代码编写单元测试。几

高效易用的C++单元测试框架:轻松构建高质量代码

单元测试是构建稳定、高质量的程序、服务或系统的必不可少的一环。通过单元测试,我们可以在开发过程中及时发现和修复代码中的问题,提高代码的质量和可维护性。同时,单元测试也可以帮助我们更好地理解代码的功能和实现细节,从而更好地进行代码重构和优化。

一台不容错过的Java单元测试代码“永动机”

作者:京东零售陈志良作为一名京东的软件匠人,我们开发的软件支撑着数亿的用户,责任是重大的,因此我们深深地敬畏每一行代码,那如何将我们的失误降到最低呢?那就是单元测试,它会让我们树立对代码的自信心。为此我们期望能打造一台生产Java单元测试代码的“永动机”,

Jmeter+Ant+Jenkins接口自动化测试框架搭建for Windows

前言软件开发的V模型大家都不陌生,其中测试阶段分为单元测试→功能测试→系统测试→验收测试。其中单元测试一般由开发同学们自己完成,大部分测试具体实施(这里不包括用例设计)是从单体功能测试开始着手的。!(https://usergoldcdn.xitu.io/2018/11/12/16706895ac09c25d?imageView2/0/