背景
powermock相比mockito相比多了很多的功能,最主要是可以模拟静态方法和私有方法,本文就来总结下使用powermock过程中的几个知识点
powermock注意事项
1.powermock私有方法时支持多次抛出异常后再返回正常结果,或者多次返回正常结果后抛出异常,由于没有mockito.doReturn().doReturn.doThrow()的写法,所以需要以下写法才可以支持:
((PowerMockitoStubber) ((PowerMockitoStubber) PowerMockito.doThrow(new RuntimeException("first Exception"))
.doThrow(new RuntimeException("sec Exception"))).doReturn(respList)).when(service)
.call(Mockito.anyList());
((PowerMockitoStubber) ((PowerMockitoStubber) PowerMockito.doReturn(respList)
.doReturn(respList1)).doThrow(new RuntimeException("sec Exception"))).when(service)
.call(Mockito.anyList());
核心要点就是每次doReturn或者doThrow后都强制进行类型转换,转换成PowerMockitoStubber类对象.
2.powermock没法修改某个类变量实例,那么我们使用到这个类变量的时候应该怎么做?比如public class A{private static Service service;},如何mock这个Service服务类?
我们可以使用反射类设置这个静态变量的值:
public static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
当我们具体使用的时候就可以使用
setFinalStatic(A.class.getDeclaredField(“service”), serviceMock);的形式注入进去了
3.powermock如何和spring集成进行单元测试?
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
@PowerMockIgnore({"javax.management.*", "javax.net.ssl.*"})
@PrepareForTest({A.class})
@ContextConfiguration(locations = {"classpath:applicationContext-test.xml"}, inheritLocations = true)
@TestExecutionListeners({ServletTestExecutionListener.class, DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class, InitSpringProfilesExecutionListener.class})
@ActiveProfiles(value = "development")
public void BaseTest{}
spring和powermock集成后的缺点是运行非常非常慢,使用mockito+spring正常情况下一分钟肯定可以完成一个单元测试,但是使用powermock+spring集成之后完成一个单元测试至少需要10分钟,原因还没有去细查,有知道的同学可以告知一下
4.powermock中如何调用私有方法?
Whitebox.invokeMethod(inst, “method”, param);
或者
ReflectionTestUtils.invokeMethod(inst,“method”,param)
小结:
powermock非常强大,覆盖支持mockito的所有功能,对于旧代码迁移需要严格测试的场景,使用powermock进行测试可以mock绝大部分的场景,这样可以让你在迁移代码时有更多的自信