我正在使用PowerMock在junit测试中模拟静态方法,通常如下所示:
@RunWith(PowerMockRunner.class)
@PrepareForTest({Foo.class,Bar.class})
public class SomeUnitTest {
@Before
public void setUpTest() {
setUpFoo();
setUpBar();
}
private void setUpFoo() {
mockStatic(Foo.class);
when(Foo.someStaticMethod()).thenReturn(1);
}
private void setUpBar() {
mockStatic(Bar.class);
when(Bar.someStaticMethod()).thenReturn(2);
}
@Test
public void someTestCase() {
...
}
}
这工作正常,但我发现指定@PrepareForTest
注释阻止我使我的测试API灵活。
我想做的是如下:
public class MockLibraryOne {
public static void setUpLibraryOne() {
setUpFoo();
setUpBar();
}
private static void setUpFoo() {
mockStatic(Foo.class);
when(Foo.someStaticMethod()).thenReturn(1);
}
private static void setUpBar() {
mockStatic(Bar.class);
when(Bar.someStaticMethod()).thenReturn(2);
}
}
@RunWith(PowerMockRunner.class)
public class SomeUnitTest {
@Before
public void setUpTest() {
MockLibraryOne.setUpLibraryOne();
}
@Test
public void someTestCase() {
...
}
}
这里我的单元测试依赖于LibraryOne
,但它不知道LibraryOne
依赖哪些类,所以它不知道要添加到@PrepareForTest
注释的类。
我可以使SomeUnitTest
扩展MockLibraryOne
并将@PrepareForTest
注释添加到MockLibraryOne
类中,但是我将在其他单元测试中依赖于MockLibraryOne
,因此继承不是一般解决方案。
有没有一种方法可以在PowerMock下以编程方式准备类进行测试,而不是使用@PrepareForTest
注释?例如,类似以下内容:
public class MockLibraryOne {
public static void setUpLibraryOne() {
setUpFoo();
setUpBar();
}
private static void setUpFoo() {
prepareForTest(Foo.class);
mockStatic(Foo.class);
when(Foo.someStaticMethod()).thenReturn(1);
}
private static void setUpBar() {
prepareForTest(Bar.class);
mockStatic(Bar.class);
when(Bar.someStaticMethod()).thenReturn(2);
}
}
我想如果PowerMockRunner
以不同的方式处理@PrepareForTest
注释会很好:对于每个指定的类,它不应该只将类(及其层次结构)添加到类列表中以准备模拟,但是然后检查该类以查看如果它有任何@PrepareForTest
注释:
@RunWith(PowerMockRunner.class)
@PrepareForTest({MockLibraryOne.class})
public class SomeUnitTest {
...
}
@PrepareForTest({Foo.class,Bar.class})
public class MockLibraryOne {
...
}
}
因此,在@PrepareForTest
上的SomeUnitTest
注释会找到MockLibraryOne
,而@PrepareForTest
注释也会在Foo.class
和Bar.class
中拖拽。
所以也许编写我自己的测试运行器来取代PowerMockRunner
可能是一个解决方案。
或者也许有一个更简单的解决方案,例如使用PowerMockAgent
类?
编辑:模拟策略可能是一个解决方案:https://code.google.com/p/powermock/wiki/MockPolicies
编辑:模拟策略与PowerMockRunner
一起工作,但没有(似乎)与PowerMockRule
(我有时因类加载器问题而需要)。
为什么你甚至想模拟静态方法?为什么不将这些静态方法包装在可以用mockito模拟的类中呢?
class FooWraper {
void someMethod() {
Foo.someStaticMethod()
}
}
然后你可以创建一个你的FooWraper模拟器。根本不需要使用Powermock ......
也许你正在寻找一个mock policy?