和Mockito一起使用PowerMock
(源码加我QQ3177181324)
介绍
事实上,PowerMock提供了一个名为“PowerMockito”的类,用于创建mock对象/类并开始验证和期望(一个行为/调用或者返回值),您仍然可以使用Mockito设置和验证期望的所有其他内容(例如times(),anyInt())。
所有的用法需要@RunWith(PowerMockRunner.class),并在类上标识@PrepareForTest注解。
支持版本
PowerMock 2.0.0及更高版本具有Mockito 2的支持。
PowerMock 1.7.0及更高版本具有Mockito 2的实验性支持。
许多问题仍未解决。PowerMock使用Mockito 内部API,但至少可以同时使用两个模拟框架。
| Mockito | PowerMock |
|---|---|
| 2.8.9+ | 2.x |
| 2.8.0-2.8.9 | 1.7.x |
| 2.7.5 | 1.7.0RC4 |
| 2.4.0 | 1.7.0RC2 |
| 2.0.0-beta - 2.0.42-beta | 1.6.5-1.7.0RC |
| 1.10.8 - 1.10.x | 1.6.2 - 2.0 |
| 1.9.5-rc1 - 1.9.5 | 1.5.0 - 1.5.6 |
| 1.9.0-rc1 & 1.9.0 | 1.4.10 - 1.4.12 |
| 1.8.5 | 1.3.9 - 1.4.9 |
| 1.8.4 | 1.3.7 & 1.3.8 |
| 1.8.3 | 1.3.6 |
| 1.8.1 & 1.8.2 | 1.3.5 |
| 1.8 | 1.3 |
| 1.7 | 1.2.5 |
Maven配置
JUnit
- Mockito JUnit Maven配置
- Mockito2 JUnit Maven配置
TestNG
- Mockito TestNG Maven配置
- Mockito2 TestNG Maven配置
用法
在下面的示例中,为了更好地了解方法的位置,我们在Mockito或PowerMockito API中未对方法使用静态导入。但是,我们强烈建议您在实际的测试用例中静态导入方法,以提高可读性。
注意:Mockito团队在Mockito 2.1.0中增加了模拟final类/方法的能力。自PowerMock 1.7.0(经过Mockito 2.8.9测试)以来,PowerMock支持此功能。可以使用PowerMock Configuration启用该功能。如果使用Mockito 2,建议使用Mockito模拟final方法/类。
Mock静态方法
如何模拟(mock)和存根(stub):
- 在类上添加
@PrepareForTest。
@PrepareForTest(Static.class) // Static.class contains static methods
- 调用
PowerMockito.mockStatic()以Mock静态类(用PowerMockito.spy(class)mock特定方法):
PowerMockito.mockStatic(Static.class);
- 只需使用Mockito.when()来设置您的期望:
Mockito.when(Static.firstStaticMethod(param)).thenReturn(value);
注意:如果需要模拟java系统类加载器/bootstrap类加载器(在java.lang或java.net等中定义的类)加载的类,则需要使用此方法。
如何验证行为
静态方法的验证分两个步骤进行。
- 首先调用
PowerMockito.verifyStatic(Static.class)以开始验证行为,然后 - 调用的静态方法
Static.class进行验证。例如:
PowerMockito.verifyStatic(Static.class); // 1
Static.firstStaticMethod(param); // 2
重要提示:您需要按方法逐个调用verifyStatic(Static.class)验证。
如何使用参数匹配器
Mockito匹配器可能仍适用于PowerMock mock。例如,对每个mock的静态方法使用自定义参数匹配器:
PowerMockito.verifyStatic(Static.class);
Static.thirdStaticMethod(Mockito.anyInt());
如何验证确切的调用次数
您仍然可以将Mockito.VerificationMode(例如Mockito.times(x))与PowerMockito.verifyStatic(Static.class, Mockito.times(2))结合使用:
PowerMockito.verifyStatic(Static.class, Mockito.times(1));
如何将静态void方法存根以引发异常
如果不是私有方法:
PowerMockito.doThrow(new ArrayStoreException("Mock error")).when(StaticService.class);
StaticService.executeMethod();
请注意,您可以对final类/final方法执行相同的操作:
PowerMockito.doThrow(new ArrayStoreException("Mock error")).when(myFinalMock).myFinalMethod();
对于私有方法,请使用PowerMockito.when,例如:
when(tested, "methodToExpect", argument).thenReturn(myReturnValue);
Mock,存根和验证静态方法的完整示例
@RunWith(PowerMockRunner.class)
@PrepareForTest(Static.class)
public class YourTestCase {
@Test
public void testMethodThatCallsStaticMethod() {
// mock all the static methods in a class called "Static"
PowerMockito.mockStatic(Static.class);
// use Mockito to set up your expectation
Mockito.when(Static.firstStaticMethod(param)).thenReturn(value);
Mockito.when(Static.secondStaticMethod()).thenReturn(123);
// execute your test
classCallStaticMethodObj.execute();
// Different from Mockito, always use PowerMockito.verifyStatic(Class) first
// to start verifying behavior
PowerMockito.verifyStatic(Static.class, Mockito.times(2));
// IMPORTANT: Call the static method you want to verify
Static.firstStaticMethod(param);
// IMPORTANT: You need to call verifyStatic(Class) per method verification,
// so call verifyStatic(Class) again
PowerMockito.verifyStatic(Static.class); // default times is once
// Again call the static method which is being verified
Static.secondStaticMethod();
// Again, remember to call verifyStatic(Class)
PowerMockito.verifyStatic(Static.class, Mockito.never());
// And again call the static method.
Static.thirdStaticMethod();
}
}
部分Mock
您可以通过使用PowerMockito的PowerMockito.spy部分mock方法。请注意(以下内容取自Mockito文档,同样适用于PowerMockito):有时,无法使用标准when(..)方法对spy()进行打桩(stubbing,存根)。例如:
List list = new LinkedList();
List spy = spy(list);
//这样是不行的:真正的方法spy.get(0)会被调用并抛出IndexOutOfBoundsException异常(这个list仍然是空的)
//when(spy.get(0)).thenReturn("foo");
//你需要用 doReturn() 去打桩
doReturn("foo").when(spy).get(0);
如何验证行为
只需使用Mockito.vertify()进行标准验证:
Mockito.verify(mockObj, times(2)).methodToMock();
如何验证private行为
使用PowerMockito.verifyPrivate(),例如
verifyPrivate(tested).invoke("privateMethodName", argument1);
这也适用于私有静态方法。
如何mock新对象的构造
使用PowerMockito.whenNew,例如
whenNew(MyClass.class).withNoArguments().thenThrow(new IOException("error message"));
请注意,您必须准备在测试过程中的用于创建MyClass新实例中的类,而不是其MyClass本身。例如,如果正在执行的类称为X,则必须先进行操作@PrepareForTest(X.class)才能使whenNew工作:
@RunWith(PowerMockRunner.class)
@PrepareForTest(X.class)
public class XTest {
@Test
public void test() {
whenNew(MyClass.class).withNoArguments().thenThrow(new IOException("error message"));
X x = new X();
x.y(); // y is the method doing "new MyClass()"
..
}
}
如何验证新对象的构造
使用PowerMockito.verifyNew,例如
verifyNew(MyClass.class).withNoArguments();
如何使用参数匹配器
如何使用参数匹配器mock:
Mockito.verify(mockObj).methodToMock(Mockito.anyInt());
Spy的完整示例
@RunWith(PowerMockRunner.class)
// We prepare PartialMockClass for test because it's final or we need to mock private or static methods
@PrepareForTest(PartialMockClass.class)
public class YourTestCase {
@Test
public void spyingWithPowerMock() {
PartialMockClass classUnderTest = PowerMockito.spy(new PartialMockClass());
// use Mockito to set up your expectation
Mockito.when(classUnderTest.methodToMock()).thenReturn(value);
// execute your test
classUnderTest.execute();
// Use Mockito.verify() to verify result
Mockito.verify(mockObj, times(2)).methodToMock();
}
}
私有方法部分mock的完整示例
(在PowerMock版本1.3.6+中可用)
@RunWith(PowerMockRunner.class)
// We prepare PartialMockClass for test because it's final or we need to mock private or static methods
@PrepareForTest(PartialMockClass.class)
public class YourTestCase {
@Test
public void privatePartialMockingWithPowerMock() {
PartialMockClass classUnderTest = PowerMockito.spy(new PartialMockClass());
// use PowerMockito to set up your expectation
PowerMockito.doReturn(value).when(classUnderTest, "methodToMock", "parameter1");
// execute your test
classUnderTest.execute();
// Use PowerMockito.verify() to verify result
PowerMockito.verifyPrivate(classUnderTest, times(2)).invoke("methodToMock", "parameter1");
}
}
Mockito mock-maker-inline
在PowerMock版本1.7.0中可用
Mockito团队在Mockito 2.1.0中增加了对final类/方法进行mock的支持。通过在src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker中添加包含以下一行的文件,可以在PowerMock中启用此功能 :
mock-maker-inline
复制代码
PowerMock实现了自己的MockMaker,这导致与Mockito的mock-maker-inline不兼容,即使PowerMock只是作为依赖添加而未使用。如果在类路径中存在两个org.mockito.plugins.MockMaker,则只能使用其中一个,但不确定是哪一个。
但是PowerMock可以将调用委托给另一个MockMaker,因此无需PowerMock即可运行测试。从PowerMock 1.7.0开始,可以使用PowerMock Configuration进行配置 。
该MockMaker可以通过创建org/powermock/extensions/configuration.properties文件来配置和设置:
mockito.mock-maker-class=mock-maker-inline
复制代码
将Mockitomock-maker-inline与PowerMock结合使用的示例: github.com/powermock/p…
如果觉得文章对你有帮助,麻烦 点赞、评论、收藏 你的支持是我最大的动力!!!
然后小编在学习过程中整理了一些学习资料,需要的可以加入我的学习交流群323432957 或加微dingyu-002即可免费获取Python自动化测开及Java自动化测开学习资料(里面有功能测试、性能测试、python自动化、java自动化、测试开发、接口测试、APP测试等多个知识点的架构资料)

本文介绍了如何在Java测试中将PowerMock与Mockito结合使用,包括Mock静态方法、部分Mock、验证行为和private行为,以及如何配置Maven项目。提供了详细用法示例和注意事项。
3156

被折叠的 条评论
为什么被折叠?



