【发布时间】:2013-11-07 22:27:16
【问题描述】:
我正在使用 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 {
...
}
}
因此,在此SomeUnitTest 上的@PrepareForTest 注释会找到MockLibraryOne,而@PrepareForTest 注释也会拖入Foo.class 和Bar.class。
所以也许编写我自己的测试运行器来替换 PowerMockRunner 可能是一个解决方案。
或者也许有更简单的解决方案,例如使用PowerMockAgent 类?
编辑:模拟策略可能是一种解决方案:https://code.google.com/p/powermock/wiki/MockPolicies
编辑:模拟策略适用于PowerMockRunner,但不适用于(似乎)PowerMockRule(由于类加载器问题,我有时需要)。
【问题讨论】:
-
我也面临同样的问题。你找到解决办法了吗?
-
你知道你可以为每个方法而不是每个类使用@PrepareForTest注解吗?
标签: unit-testing junit powermock