mockito框架上手非常简单,但是它也有弊端和局限性,不能mock静态方法、私有方法、构造方法等,但powermockito框架很好的弥补了这一缺陷。 版本说明 一般powermockito和mockito配合来使用,有相应的版本要求。 powermockito mockito 1.6.5+ 2.0.0-beta – 2.0.42-beta 1.10.19 1.6.4 1.10.8 – 1.10.x 1.6.2+ 1.9.5-rc1 – static方法中调用static方法,但我们并不想mock静态方法中的任何代码,就需要给这个static方法mock一个返回值,mockito框架就无能为力了,因为它并不能mock静态方法,所以需要配合powermockito static OngoingStubbing when(Object instance, String methodName, Object… arguments) throws Exception; PowerMockito.when
powerMockito单元测试准备 1 在需要执行单测的类上注解@RunWith(PowerMockRunner.class) 2 对于需要mock私有方法的需要注解@PrepareForTest(FooServiceImpl.class
junit4整合PowerMockito进行单元测试 一、介绍 在单元测试中,代码里面往往有一些需要连接数据库、调用第三方远程的代码。 由于没有环境,这些代码的存在,会给单元测试造成影响。 本文使用的是PowerMockito,它是由Mockito的基础上开发而来,语法规则基本一致,同时也有一些自己的增强,可以对静态方法,局部变量进行mock。 (File.class); // mock PowerMockito.whenNew(File.class) .withAnyArguments () .thenReturn(file); PowerMockito.when(file.length()).thenReturn(2L); , "powerMockitoUtil"); field.set(powerMockitoServiceImplUnderTest, util); PowerMockito.when
使用PowerMockito如何阻止静态代码块的运行一、前言在我进行单元测试mock静态类的时候,突然出现了这个异常我就很懵逼啊,无奈只能一步一步的进去查找问题结果发现问题出现在静态类当中,那是肯定的, org.junit.Test;import org.junit.runner.RunWith;import org.mockito.InjectMocks;import org.powermock.api.mockito.PowerMockito 但它在正常的容器下运行就是正常且必须的那么我们就得想办法绕过去了,正好PowerMockito提供了一个注解,可以帮助我们取消静态代码块的执行@SuppressStaticInitializationFor org.junit.Test;import org.junit.runner.RunWith;import org.mockito.InjectMocks;import org.powermock.api.mockito.PowerMockito powerMockitoServiceImplUnderTest; @Test public void testExecludeStaticCode() { // 设置参数 PowerMockito.mockStatic
使用PowerMockito如何对私有方法进行mock一、介绍最近,正在进行单元测试的补充,然后就遇到了一个令人头疼的问题;我有一个publicMethod方法,在当中调用了privateMethod方法 org.junit.Test;import org.junit.runner.RunWith;import org.mockito.InjectMocks;import org.powermock.api.mockito.PowerMockito void testPublicMethod() throws Exception { // 设置参数 powerMockitoServiceImplUnderTest = PowerMockito.spy (powerMockitoServiceImplUnderTest); PowerMockito.doNothing() .when(powerMockitoServiceImplUnderTest , PowerMockito.method(PowerMockitoServiceImpl.class, "privateMethod", String.class)) .
使用PowerMockito如何对私有方法进行单元测试一、介绍在上一篇文章中,讲解了公共方法调用私有方法的测试,我们只想对公共方法进行验证测试,私有方法进行mock即可那么在本篇中,如何对私有方法进行单元测试呢 org.junit.runner.RunWith;import org.mockito.InjectMocks;import org.mockito.Mock;import org.powermock.api.mockito.PowerMockito testPrivateMethodNeedTest() throws InvocationTargetException, IllegalAccessException { // 设置参数 PowerMockito.when (powerMockitoMapper.updateById(any())).thenReturn(1); // 运行测试 Method testMethod = PowerMockito.method
(HeartConfig.class); PowerMockito.doReturn(120).when(heartConfig).getMinHeart(); PowerMockito.doReturn SyncInformHandler syncInformHandler = PowerMockito.mock(SyncInformHandler.class); PowerMockito.doReturn (IMInternal.class); PushInfo pushInfo = PowerMockito.mock(PushInfo.class); PowerMockito.doReturn(pushInfo ()来监视这个real object List list = new LinkedList(); List spy = PowerMockito.spy(list); PowerMockito.doReturn ()区别在于Mockito无法监视对象的final方法,但是PowerMockito可以,其实PowerMockito是基于Mockito的基础上拓展开发的,所以功能更加强大,也兼容了Mockito的功能
mockPublicMethod() throws Throwable { String type = UUID.randomUUID().toString(); PowerMockito.when (DemoDao.class); PowerMockito.when(DemoDao.mockStaticMethod(any())).thenReturn(type); Throwable { String type = UUID.randomUUID().toString(); // 重点这一句 demoService = PowerMockito.spy (demoService); PowerMockito.doReturn(type).when(demoService,"callPrivateMethodThrowable",type (AbstractDemo.class, "getExtendMethod"); // InvocationHandler PowerMockito.replace
框架使用 Mockito框架基本满足需求但是有一些局限性,如对static、final、private等方法不能mock,PowerMockito就可以解决这些问题,PowerMockito是一个扩展了其它如 这里PowerMockito.verifyStatic(Utils.class)其实等同于PowerMockito.verifyStatic(Utils.class, times(1)),如果想验证超过一次的 PowerMockito.when(Utils.getUUId()).thenCallRealMethod(); //与下面等价 //PowerMockito.doCallRealMethod().when (CommonExample.class); PowerMockito.when(commonExample.callPrivateMethod()).thenCallRealMethod(); PowerMockito.when 本身已经有对Mockito的依赖库支持了,所以只依赖PowerMockito就可以了。
其次我们需要在类初始化代码中对这个类进行Mock,语法如下: PowerMockito.mockStatic(HttpBase.class) PowerMockito.mockStatic (NewUtil.class) 下面演示一下如何自定义静态方法的行为: PowerMockito.when(HttpBase.fetchServiceNames()).thenReturn IService) def drive = new TaskScheduled(IService: service, cid: "") def setupSpec() { PowerMockito.mockStatic (HttpBase.class) PowerMockito.mockStatic(NewUtil.class) PowerMockito.when(HttpBase.fetch ) setMethod("GET") } }]) //这里因为send方法中用到了这个静态方法 PowerMockito.when
准备静态类的Mock PowerMockito.mockStatic(IdGenerator.class); // 2. 验证私有方法被调用(可选) PowerMockito.verifyPrivate(spyService,Mockito.times(2)) .invoke 预设final方法行为 PowerMockito.when(mockUtility.finalMethod()).thenReturn("Mocked final"); (FinalUtility.class); PowerMockito.when(FinalUtility.staticFinalMethod()).thenReturn("Mocked (PowerMockito.method(ConfigurationLoader.class, "loadConfigurationFromRemote")); //
demo案例的测试用例如下 import static org.junit.Assert.assertEquals; import static org.powermock.api.mockito.PowerMockito.doReturn ; import static org.powermock.api.mockito.PowerMockito.mock; import java.io.BufferedReader; import java.io.FileInputStream BufferedReader.class); FileInputStream inputStreamMock= mock(FileInputStream.class); PowerMockito.whenNew thenReturn(bufferedReaderMock); PowerMockito.whenNew(FileInputStream.class). thenReturn(inputStreamMock); PowerMockito.whenNew(InputStreamReader.class).
(File.class); ClassUnderTest underTest = new ClassUnderTest(); PowerMockito.whenNew(File.class ).withArguments("bbb").thenReturn(file); PowerMockito.when(underTest.callArgumentInstance( new File("bbb"))).thenReturn(true); PowerMockito.when(file.exists()).thenReturn(true); Assert.assertTrue (ClassDependency.class); ClassUnderTest underTest = new ClassUnderTest(); PowerMockito.when (ClassUnderTest.class); PowerMockito.when(underTest,"callPrivateMethod").thenCallRealMethod();
mock新建对象 如果我们要对一个实体对象Bean进行Mock,只需要这样写PowerMockito.whenNew(User.class).withAnyArguments().thenReturn( 方式一: PowerMockito.doNothing().when(userMapper, "updateUser", new User()); 在when方法中传入userMapper类实例, PowerMockito.mockStatic(DateUtil.class); 同时被mock的类必须要在@PrepareForTest注解中指定,像本例中的DateUtil类。 如下所示: UserServiceImpl spy = PowerMockito.spy(userServiceImpl); PowerMockito.when(spy, "verifyId (userServiceImpl); PowerMockito.when(spy, "verifyId", 0).thenReturn(true); PowerMockito.when
使用示例 4.1 模拟接口返回 首先对接口进行mock,然后录制相关行为 InterfaceToMock mock = Powermockito.mock(InterfaceToMock.class) Powermockito.when(mock.method(Params…)).thenReturn(value) Powermockito.when(mock.method(Params..)). (FinalClassToMock.class); Powermockito.when(StaticClassToMock.method(Object.. params)).thenReturn(Object 4.7 使用spy方法避免执行被测类中的成员函数 如被测试类为:TargetClass,想要屏蔽的方法为targetMethod. 1) PowerMockito.spy(TargetClass.class 如:Mockito.anyInt(),Mockito.anyString() 4.9 处理public void型的静态方法 Powermockito.doNothing.when(T class2mock
); LambdaQueryChainWrapper wrapper3 = PowerMockito.mock(LambdaQueryChainWrapper.class); wrapper5 = PowerMockito.mock(LambdaQueryChainWrapper.class); List list = PowerMockito.mock(ArrayList.class ); PowerMockito.doReturn(wrapper1).when(resourceSubOrderRepository).lambdaQuery(); // (), any(), any()); PowerMockito.doReturn(wrapper3).when(wrapper2).eq(anyBoolean(), any(), any ()); PowerMockito.doReturn(wrapper4).when(wrapper3).eq(any(), any()); PowerMockito.doReturn
org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.rule.PowerMockRule; import static org.powermock.api.mockito.PowerMockito.spy ; import static org.powermock.api.mockito.PowerMockito.doThrow; import static org.junit.Assert.assertEquals ; /** * Test class to demonstrate static mocking with PowerMockito. */ //@RunWith(PowerMockRunner.class 得益于Powermockito对于静态方法进行Mock的能力,使用如下格式,就实现了预期的调用Thread.sleep时抛出中断异常的行为,从而实现了大大缩短程序执行时间的目标。 Thread.sleep(Mockito.anyLong()); 当然,为了能够mock某个类的静态方法,需要在测试类上加上一下注解, @PrepareForTest( { SystemClass.class}) 并且使用Powermockito.spy
在修改单元测试的过程中,不幸踩了个坑,发现 Powermockito 的PowerMock.mockStatic(ClassThatContainsStaticMethod.class) 在多线程场景下是无法正常工作的 ,这再次验证了之前 ThrougthWorks 顾问说的那句话: 除非万不得已,或者是Mock遗留系统接口,否则不要使用Powermockito。 由于我不是Powermockito的专家,所以无法深入的去探究这个问题的原因,但是我想,这应该是和静态方法本身在一个JVM内的唯一性有关,我截取了网上两个解释供参考: Explanation 1 Without
Powermockito.mock():主要是通过class创建对应的mock对象,不同于easymock等使用proxy(代理)的方式创建,而是在运行过程中动态修改class字节码文件的形式来创建。 这个方法即可完成验证,具体示例代码如下: @Test public void testCreateStudentWithMock() { StudentDao studentDao = PowerMockito.mock (StudentDao.class); Student student=new Student(); PowerMockito.doNothing().when(studentDao
org.mockito.InjectMocks;import org.mockito.Mock;import org.mockito.MockitoAnnotations;import org.powermock.api.mockito.PowerMockito org.assertj.core.api.Assertions.assertThat;import static org.mockito.ArgumentMatchers.any;import static org.powermock.api.mockito.PowerMockito.doReturn ;import static org.powermock.api.mockito.PowerMockito.when;@RunWith(PowerMockRunner.class)public class templateParam(templateParam).build();AndroidAppPipelineConfigService androidAppPipelineConfigServiceSpy = PowerMockito.spy