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);//办法二@Mockprivate OrderInfo orderInfo;@Beforepublic void setUp(){MockitoAnnotations.initMocks(this);}
3.2 定义被测试对象
把被测试服务类进行实例化
@InjectMocksprivate OrderServiceImpl orderService;
3.3 模仿枚举类型/静态方法
须要把对应的模仿类放在@PrepareForTest中
//必须增加@RunWith和@PrepareForTest在类前@RunWith(PowerMockRunner.class)@PrepareForTest(OrderTypeEnum.class)//在@Before中增加枚举mock@Beforepublic 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 转载请注明起源