PowerMockito 使用

概述

PowerMock扩展了EasyMock和Mockito框架,增加了对static和final方法mock支持等功能.
PowerMock有两个重要的注解:
 @RunWith(PowerMockRunner.class)
 @prepareForTest({MyObject.class})

 @PrepareForTest注解和@RunWith注解是结合使用的,不要单独使用@PrepareForTest,否则不起作用。当使用PowerMock去mock静态,final或者私有方法时,需要加上这两个注解。
另外还有其他注解,会在下面的使用中说明。

使用方法

1. 添加依赖
<dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito-common</artifactId>
            <version>1.6.5</version>
        </dependency>

        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>1.6.3</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito</artifactId>
            <version>1.6.5</version>
            <scope>test</scope>
        </dependency>
2. 声明mock对象
声明Mock对象有两种方式,一种是直接使用代码,另一种是使用mockito的@Mock和@InjectMocks 注解.
  • - 直接代码声明
OrderRechargeService mock = PowerMockito.mock(OrderRechargeService.class);
  • - 使用注解
@Mock 和@InjectMocks是不同的注解,不能相提并论,其中@Mock就是mock对象,而@InjectMocks是用来标注待测试类的,当测试时,@Mock标注的类会被注入到用@InjectMocks标注的类中。
@Mock
private OrderRechargeService rechargeService;
@InjectMocks
private OrderRechargeHandlerResultGatewayServiceImpl service;
当使用注解时,需要有个注解的类的一个初始化过程,有两种方式:
1. 添加@Runwith(PowerMockRunner.class)的注解,
2. 在setUp方法中显示初始化:MockitoAnnotations.initMocks(this);

3. 使用Mock对象
mock 构造方法、final方法、private 方法、static方法 需要在测试类添加@PrepareForTest()注解,其中mock构造方法,@PrepareForTest中的类是所在类,其他的都是方法所属类。
普通Mock
PowerMockito.when(orderRechargeService.updateByRequestNo(Matchers.any())).thenReturn(true);
/**
* mock 无返回值的方法
*/
PowerMockito.doNothing().when(mockService).methodWithVoid();
/**
* 当使用mock对象去调用某个方法时,要使用thenCallRealMethod();
*/   
PowerMockito.when(mock,"methodName").thenCallRealMethod();

Mock 构造方法

File file = PowerMockito.mock(File.class);   
PowerMockito.whenNew(File.class).withArguments("bing").thenReturn(file);   
mock final 方法
ClassWithFinalMethod mock= PowerMockito.mock(ClassWithFinalMethod.class); 
PowerMockito.when(mock.finalMethod()).thenReturn(someThing);  
mock private 方法
PowerMockito.when(service,"privateMethod").thenReturn(someThing);
mock 静态方法
PowerMockito.mockStatic(ClassWithStaticMethod.class);
PowerMockito.when(ClassWithStaticMethod.staticMethod()).thenReturn(someThing);  
设置field 
Whitebox.setInternalState(service, "anyfield", value);  
Whitebox.getInternalState(service,"field");
answer:根据不同的输入返回不同的结果
PowerMockito.when(service.method()).then(new Answer<methodReturnObject>(){
	public methodReturnObject answer(InvocationOnMock invocation){
		invocation.callRealMethod():调用真正的方法
		invocation.getArguments():获取所有参数
		invocation.getMethod():返回mock实例调用的方法
		invocation.getMock():获取mock实例
			
		if ... return null;
	}
});
suppress 禁用
PowerMockito.suppress方法用来禁用某个域或方法.
PowerMockito.suppress(PowerMockito.constructor(BaseEntity.class)):表示禁用BaseEntity的构造函数
PowerMockito.suppress(PowerMockito.constructor(BaseEntity.class, String.class,  Integer.class)):表示禁用参数为String和Integer类型的BaseEntity构造方法。
PowerMockito.suppress(PowerMockito.method(BaseEntity.class, "performAudit", String.class)):表示禁用BaseEntity的performAudit方法。
@SuppressStaticInitializationFor("BaseEntity"):表示禁用BaseEntity的静态初始化。注意引号部分通常需要全名,比如"com.gitshah.powermock.BaseEntity"。
PowerMockito.suppress(PowerMockito.field(BaseEntity.class,"identifier")):禁用identifier域。

4. assert or verify 
  • - 验证方法是否调用
Mockito.verify(mockService).mockedMethod(parameters);
  • - 验证方法是否从未调用
Mockito.verify(mockService,never()).mockedMethod(parameters);
  • - 验证方法调用次数
Mockito.verify(mockService,times(1)).mockedMethod(parameters);
  • -验证是否调用过private方法
PowerMockito.verifyNew();
PowerMockito.verifyPrivate();
PowerMockito.verifyStatic();

总结

另外还有一些高级用法,如只Mock 部分方法,使用spy()等等,后续会补充.


  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值