powermock静态类_如何使用Powermock对静态方法进行mock

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

powermock静态类_如何使⽤Powermock对静态⽅法进⾏
mock
在平常⼯作过程中,总会设计些⼯具类,⾥⾯通常使⽤静态⽅法来实现。

那么如何来对这些静态⽅法进⾏mock,以及如何验证静态⽅法被调⽤?下⾯简单介绍下如何使⽤Powermock来实现针对静态⽅法的mock。

⾸先我们设计⼀个静态类如下(Utility.java):
public class Utility {
public static boolean listIsNullOrEmpty(List objectList) {
return objectList == null || objectList.isEmpty();
}
public static boolean listIsNotNullOrEmpty(List objectList) {
return objectList != null && !objectList.isEmpty();
}
}
被测试类如下(UtilityHelper.java):
public class UtilityHelper {
public int sum(List dataLst) {
if (Utility.listIsNullOrEmpty(dataLst)) {
return 0;
}
int total = 0;
for (Integer data : dataLst) {
total += data;
}
return total;
}
public int product(List dataList) {
int total = 1;
if (Utility.listIsNotNullOrEmpty(dataList)) {
for (Integer data : dataList) {
total *=data;
}
}
return total;
}
}
在被测试类中分别定义了两个⽅法,分别调⽤了Utility类⾥⾯的两个静态⽅法,下⾯我们通过对这两个⽅法进⾏测试,来介绍下使⽤Powermock对静态⽅法进⾏mock的各种⽤法。

测试类如下(UtilityHelperTest.java):
@RunWith(PowerMockRunner.class)
@PrepareForTest({Utility.class})
public class UtilityHelperTest {
private UtilityHelper utilityHelper;
private List dataList;
@Before
public void setUp() {
PowerMockito.mockStatic(Utility.class);
dataList = new ArrayList();
dataList.add(1);
dataList.add(2);
dataList.add(3);
utilityHelper = new UtilityHelper();
}
@Test
public void testSum_1() {
PowerMockito.when(Utility.listIsNullOrEmpty(Mockito.anyList())).thenReturn(true);
int sum = utilityHelper.sum(dataList);
Assert.assertEquals(0, sum);
PowerMockito.verifyStatic(Mockito.times(1));
Utility.listIsNullOrEmpty(Mockito.anyList());
}
@Test
public void testSum_2() {
PowerMockito.when(Utility.listIsNullOrEmpty(Mockito.anyList())).thenReturn(false);
int sum = utilityHelper.sum(dataList);
Assert.assertEquals(6, sum);
}
@Test
public void testProduct_1() {
int product = utilityHelper.product(dataList);
Assert.assertEquals(1, product);
}
@Test
public void testProduct_2() {
PowerMockito.spy(Utility.class);
int product = utilityHelper.product(dataList);
Assert.assertEquals(6, product);
}
@Test
public void testProduct_3() {
PowerMockito.when(Utility.listIsNotNullOrEmpty(Mockito.anyList())).thenCallRealMethod();
int product = utilityHelper.product(dataList);
Assert.assertEquals(6, product);
}
}
如果想要对某个类的静态⽅法进⾏mock,则必须在PrepareForTest后⾯加上相应的类名, ⽐如此例的Utility.class。

在对该类的某个⽅法进⾏mock之前,还必须先对整个类进⾏mock:
PowerMockito.mockStatic(Utility.class);
在testSum_1⽅法中,我们对listIsNullOrEmpty进⾏了mock:
PowerMockito.when(Utility.listIsNullOrEmpty(Mockito.anyList())).thenReturn(true);
可以看到虽然⼊参⾮空,但是由于返回值返回了true,使得调⽤sum⽅法返回的值是0。

另外,如果我们想要验证某静态⽅法是否被调⽤,或者被调⽤了⼏次,我们可以⽤如下⽅式验证:
PowerMockito.verifyStatic(Mockito.times(1));
Utility.listIsNullOrEmpty(Mockito.anyList());
先使⽤verifyStatic⽅法表明要验证静态⽅法,可以带参数,也可以不带参数,其参数可以使⽤Mockito的times⽅法或never⽅法来表⽰其调⽤次数。

下⾯紧跟着的⼀⾏则表⽰要验证的是哪个已经mock的静态⽅法。

在test_sum2⽅法中,由于我们mock的返回值为false,所以调⽤sum⽅法返回的是实际值。

在test_product1中,我们可以看到并没有对product中调⽤的listIsNotNullOrEmpty进⾏mock,那么为什么返回值是 1 呢?
这个主要是因为我们在setup⽅法中对使⽤mockStatic⽅法对Utility.class进⾏了mock,那么此时该类中的所有⽅法实际上都已经被mock 了,如果没有对某个⽅法进⾏具体mock返回值,则调⽤该⽅法时,会直接返回对应返回类型的默认值,并不会执⾏真正的⽅法。

此例对于listIsNotNullOrEmpty⽅法来说,其返回类型为boolean型,其默认值为false,所以product⽅法返回 1 。

那么如果我们想对已经mock的类的某个⽅法调⽤真实的⽅法,⽽不是调⽤mock⽅法,那么该如何处理呢?此处我们介绍两种实现:
在test_product2中,我们看到相对test_product1来说,多了⼀⾏:
PowerMockito.spy(Utility.class);
加了上⾯⼀⾏后,虽然也没有对listIsNotNullOrEmpty进⾏mock,但此时返回值是真正的值,说明没有调⽤默认的mock⽅法。

使⽤spy 后,虽然已经对该类做了mockStatic处理,但此时该类中的所有⽅法仍然都会调⽤真实的⽅法,⽽不是默认的mock⽅法。

这种⽤法主要适⽤于只想要对某个类的少量⽅法进⾏mock,其他⽅法仍然执⾏真正的⽅法,平常写时,可以紧跟在mockStatic⽅法后。

我们在看下test_product3中,该⽅法相对test_product1中,多了⼀⾏:
PowerMockito.when(Utility.listIsNotNullOrEmpty(Mockito.anyList())).thenCallRealMethod();
此⾏的含义就是调⽤到mock类的该⽅法执⾏真正的⽅法,⽽不是mock⽅法。

这种⽅式就是需要对每个要执⾏的⽅法都要进⾏相应的mock 处理。

上述两种⽅式,可以根据⾃⼰的需要进⾏选择使⽤哪⼀种。

但是⼀定要记得,只要使⽤了mockStatic某类时,该类中的所有⽅法就已经都默认被mock了, 在调⽤该类的⽅法时,必须根据具体⽅法进⾏相应的处理。

另外,重要的事说三遍: 如果要mock静态⽅法,必须要在PrepareForTest后⾯加上该⽅法所在的类。

相关文档
最新文档