PowerMockito 快速上手记要
转眼一个月多没写博客了,这可不行啊,需要有产出激励自己才好。maven依赖结合Junit使用示例基础使用mockspywhenverify通配符测试私有方法静态方法final方法修改私有属性阻止静态方法的执行 SupressStaticInitializationFor使用注解和Spring结合结合SpringJUnit结合Spring 注解执行参考来源maven依赖(结合J
转眼一个月多没写博客了,这可不行啊,需要有产出激励自己才好。
maven依赖(结合Junit使用示例)
<!-- https://mvnrepository.com/artifact/org.powermock/powermock-api-mockito -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.powermock/powermock-module-junit4 -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
基础使用
mock、spy、when、verify
上述几个都是Mockito的常用静态方法
- 通过
PowerMockito.mock(Class<T> clazz)
可以创建一个mock的对象实例 - 对Mock的对象,使用类似
PowerMockito.when(mockObject.someMethod(someArg)).thenReturn(resultYouExpected)
的语法,我们可以mock对象的行为的返回值。需要注意的是:mock的对象,所有没有调用when设置过的方法,在测试时调用,返回的都是对应返回类型的默认值。 - 测试时,希望对行为进行验证,可以使用类似
PowerMockito.verify(mockObject[,times(int)]).someMethod(somgArgs)
的语法,验证mock的对象,方法是否执行过,执行过几次。 - 特别的,对于希望调用后什么都不做的,或者抛出异常的,可以使用
PowerMockito.doNothing().when(...)...
、doThrow(Throwable).when(...)...
的语法 - 如果一个对象,只希望mock它的部分方法,而其他方法希望和真实对象的行为一眼,可以使用
PowerMockito.spy(Class<T> clazz)
代替PowerMockito.mock(Class<T> clazz)
方法,其后的设置依旧,这时,没有通过when设置过的方法,测试调用时,行为和真实对象一样
通配符
可能存在这种情况:测试时对于传入的参数或者传出的参数并不关心,这时可以使用通配符:通过PowerMockito.anyInt()
、PowerMockito.anyString
、甚至PowerMockito.any(Class<T> clazz)
……来表示任意值,**需要注意的是,如果一个方法中,有一个地方使用了通配符,其他参数也都要使用通配符,对于特定的参数,不能直接指定,而需要使用PowerMockito.eq(someArg)
来通配这个参数
测试私有方法、静态方法、final方法
PowerMockito较之Mockito更好的地方就是支持对私有方法,静态方法和final方法的Mock,使用方法是:
- 在测试类上使用注解
@RunWith(PowerMockRunner.class)
- 在测试方法上使用注解
@PrepareForTest(targetClassNeedMock.class)
- 分类讨论
- 对于静态方法:@PrepareForTest的class是静态方法所在类,对这个类使用
PowerMockito.mock(Class<T> hasStaticMethodClazz)
,之后对静态方法使用PowerMockito.when(mockObject.someStaticMethod(...))...
mock,调用静态方法的被测试类即可被mock - 对于final方法:与静态方法类似,不过@PrepareForTest的class是final方法所在类
- 对于私有方法:PowerMockito提供了对私有方法的mock,使用
PowerMockito.when(mockObject,methodName:String,someArgs:Object)...
来mock私有方法,这时@PrepareForTest的class是私有方法所在类
- 对于静态方法:@PrepareForTest的class是静态方法所在类,对这个类使用
这里面需要注意的点是@PrepareForTest的class,它总代表需要特殊处理的类,而不一定是被测试类。需要特殊处理的类可能只是被测试类的一个成员变量,它可以在mock后自动注入被测试类中。
修改私有属性
在Mockito1.x和2.x,修改私有属性的方法略有不同
- 1.x的使用
Whitebox.setInternalState(mockObject,"attributeName",mockAttributeBean)
的方式可以设置私有属性 - 2.x的使用
FieldSetter.setField(mockObject,originAttrubuteBean,mockAttributeBean)
的方式来设置,这个时候,需要先获得原先mock对象内的成员变量(:Field),所以便利性降低了
阻止静态方法的执行 @SupressStaticInitializationFor
一些静态块的代码,可能测试的时候不想让它们在类加载的时候执行,这个时候,可以使用@SuppressStaticInitializationFor("会执行静态方法的全限定名")
来阻止执行
使用注解
通过使用注解来减少重复代码,使用注解,需要初始化它们,在@Before中使用MockitoAnnotations.initMocks(testClass)
来初始化
1. 使用@Mock注解声明替代mock方法
2. 使用@Spy替代spy方法
3. 使用@InjectMocks,将@Mock和@Spy的对象注入到被@InjectMocks标注的测试对象中
和Spring结合
结合SpringJUnit
很多工程都会使用到Spring,这个时候,想要测试代码,需要@Runwith(SpringJUnit4ClassRunner.class)
,但是PowerMockito也需要Runwith注解。这种情况,PowerMockito提供了新的注解@PowerMockRunnerDelegate
。
使用
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
来允许另一个Junit Runner运行
结合Spring 注解执行
我们既希望有Spring自动注入的便利,有希望有PowerMockito的便利,通过注解的配合,二者可以兼得。
对于@Spy
和@InjectMocks
标注的对象,它们同时还可以使用@Autowired
标注,这时,没有被mock的部分,将会从Spring注入进来,这些对象表现如同真实对象一样。
参考来源
更多推荐
所有评论(0)