单测利器——PowerMockito使用心得
PowerMockito是什么?
PowerMockito是一个帮助我们快速写单测的工具,如果待测试方法中调用了其他方法或远程接口(如RPC、数据库等等),但是我们又不想在单测执行过程中真正的调用,而是mock出一个数据来,那么就可以使用PowerMockito+Mockito来实现了。
为什么有Mockito了还要使用PowerMockito?
Mockito也可以在单测中mock数据,那么为什么还需要使用PowerMockito呢?
因为PowerMockito的功能更加强大,可以实现Mockito不支持的功能如Mockito无法mock静态方法,对象创建等。
如何引入
<dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>3.11.2</version><scope>test</scope></dependency><dependency><groupId>org.mockito</groupId><artifactId>mockito-all</artifactId></dependency><dependency><groupId>org.powermock</groupId><artifactId>powermock-api-mockito2</artifactId><version>${powermock.version}</version><scope>test</scope></dependency>
注意事项
@PrepareForTest注解会影响jacoo统计覆盖率
比如编写PlusUtils.java的单测的时候,如果在单测类上使用注解:
@PrepareForTest({A.class})
@Test
public class ATest{}
那么A.class这个类的单测覆盖率会统计不到,即使对某个方法单测之前调用了类似:
PowerMockito.when(A.class,"methodName").thenCallRealMethod()
也是没用的
所以如果想提高某个类的单测覆盖率,千万不要将这个类放到@PrepareForTest注解中。
mockStatic报错
在调用mockStatic的时候可能会报错,如
java.lang.ExceptionInInitializerErrorat sun.reflect.GeneratedSerializationConstructorAccessor4.newInstance(Unknown Source)at java.lang.reflect.Constructor.newInstance(Constructor.java:423)at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:48)at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)at org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:22)at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMock(SubclassByteBuddyMockMaker.java:48)at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createMock(ByteBuddyMockMaker.java:43)at org.powermock.api.mockito.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:41)at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:53)at org.mockito.internal.MockitoCore.mock(MockitoCore.java:84)at org.mockito.Mockito.mock(Mockito.java:1954)at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMethodInvocationControl(DefaultMockCreator.java:108)at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.doCreateMock(DefaultMockCreator.java:61)at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMock(DefaultMockCreator.java:53)at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.mock(DefaultMockCreator.java:40)at org.powermock.api.mockito.PowerMockito.mockStatic(PowerMockito.java:62)at com.dp.search.cloudsearch.utils.PlusUtilTest.testGetPlusByAppkey(PlusUtilTest.java:27)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:326)at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:310)at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:131)at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.access$100(PowerMockJUnit47RunnerDelegateImpl.java:59)at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner$TestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:147)at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.evaluateStatement(PowerMockJUnit47RunnerDelegateImpl.java:107)at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:298)at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:218)at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:160)at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:134)at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:136)at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:117)at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:57)at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)at org.junit.runner.JUnitCore.run(JUnitCore.java:137)at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: java.lang.IllegalArgumentException: Item may not be nullat org.apache.http.util.Args.notNull(Args.java:54)at org.apache.http.config.RegistryBuilder.register(RegistryBuilder.java:56)at com.dp.search.cloudsearch.utils.HttpClientUtil.<clinit>(HttpClientUtil.java:79)... 48 more
这种大概率是因为mock的静态类,在构造函数或者静态变量或者静态代码块执行了某些操作,导致mock失败
解决方式:单测类增加SuppressStaticInitializationFor注解,如:
@RunWith(PowerMockRunner.class)
@PrepareForTest({S3Utils.class, LionUtils.class, Lion.class, OPSUtils.class, RegionManagerLoader.class})
@SuppressStaticInitializationFor({"com.dp.search.cloudsearch.utils.HttpClientUtil","com.dp.search.cloudsearch.utils.S3Utils", "com.dp.search.cloudsearch.utils.LionUtils"})
public class AppServiceImplTest {}
SuppressStaticInitializationFor注解的意思是在mock这个静态类的时候不进行静态初始化。
单测利器——PowerMockito使用心得相关推荐
- Spock单测利器的写法
Spock是国外的测试框架,其设计灵感来自JUnit.Mockito.Groovy,可以用于Java和Groovy应用的测试. Spock简介 最近发现了一款写法简洁高效,一个单测方法可以测试多组测试 ...
- 从头到脚说单测——谈有效的单元测试
导语 非常幸运的是,从4月份至今,我能够全身心投入到腾讯新闻的单元测试专项任务中,从无知懵懂,到不断深入理解的过程,与开发同学互帮互助,受益匪浅.在此过程中,得到了质量总监.新闻总监和乔帮主的倾囊指导 ...
- Java 单测—static方法
单测-static方法 静态方法的单测 静态方法的单测 方法上加注解 @PrepareForTest({静态方法所在的类.class}) 调用测试方法前先要mock出类. @Before public ...
- 可能是全网最好的 Spock 单测入门文章!
Spock 是非常简洁规范的单元测试框架,网上很多资料都不齐全,例子也很难懂.我自己经过一段时间的学习,梳理了这篇文章,不仅讲解层次递进,而且还有非常简洁明了的例子,小白都能懂! 快速入门 Spock ...
- 百度单测生成技术如何召回线上服务的异常问题?
导读:线上系统异常问题一直以来都是使人"闻风丧胆"的,传统手段在解决这类问题时面临着相应的技术瓶颈.基于此,探索基于单元测试召回异常问题的方法,实现了一套通用且无人参与的单测生成系 ...
- 研效优化实践:Python单测——从入门到起飞
作者:uniquewang,腾讯安全平台后台开发工程师 福生于微,积微成著,一行代码的精心调试,一条指令的细心验证,一个字节的研磨优化,都是影响企业研发效能工程的细节因素.而单元测试,是指针对软件中的 ...
- jacoco + junit + mock 单测没有统计覆盖率问题
使用junit :直接在pom文件中直接引入: <properties><project.build.sourceEncoding>UTF-8</project.buil ...
- Java 单测 回滚
Java 单测 回滚 Java 在单测的时候 需要做回滚 设置如下: 需要添加以下 注解 在类上 defaultRollback = true : 为 默认全部回滚 defaultRollback = ...
- Jest + React Testing Library 单测总结
大家好,我是若川.持续组织了6个月源码共读活动,感兴趣的可以点此加我微信 ruochuan02 参与,每周大家一起学习200行左右的源码,共同进步.同时极力推荐订阅我写的<学习源码整体架构系列& ...
最新文章
- linux下查看cc攻击
- 孩子有必要学python吗_不学就落后了?孩子都能学得Python编程,究竟是什么?
- safe-rm替换系统的rm
- java写入txt文件 不替换_java非覆盖写入文件及在输出文本中换行
- vue数组中对象属性变化页面不渲染问题
- 【Siddhi 5】Siddhi 自定义函数@Extension使用
- python显示时间且更新_python显示当前时间
- LADRC的学习——用simulink搭建仿真模型
- 2017软件构造3.3
- redis cluster集群架构详解(十二)- 集群通信
- virtio-blk简易驱动
- 画出一阶系统单位阶跃响应、单位脉冲响应、单位斜坡响应曲线
- too many open files in system报错处理方案
- 这套摄像头方案太适合监控院子了!(附:安装方法+物联卡推荐)
- 【Web前端初学笔记】②HTML基本结构标签,VSCode工具创建页面,网页开发工具
- “如果没有从事研发,学习自动化的我可能在装水表”
- 光电耦合器的工作原理以及应用
- 第28届奥运会奖牌榜
- 二价--无穷价阴阳鱼函式
- Android View Binding使用介绍