I am using PowerMock to mock static methods in junit tests, typically done as follows:
@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() {
...
}
}
This works fine, but I'm finding that specifying the @PrepareForTest
annotation is preventing me from making my testing API flexible.
What I'd like to do is something like the following:
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() {
...
}
}
Here my unit test has a dependency on LibraryOne
, but it does not know which classes LibraryOne
depends on, so it does not know which classes to add to the @PrepareForTest
annotation.
I could make SomeUnitTest
extend MockLibraryOne
and add the @PrepareForTest
annotation to the MockLibraryOne
class, but I will have dependencies on more than just MockLibraryOne
in other unit tests, so inheritance is not a general solution.
Is there some way of programmatically preparing a class for testing under PowerMock, instead of using the @PrepareForTest
annotation? For example, something like the following:
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);
}
}
I guess it would be nice if PowerMockRunner
processed the @PrepareForTest
annotation a little differently: for each specified class, it should not only add that class (and its hierarchy) to the list of classes to prepare for mocking, but then examine that class to see if it has any @PrepareForTest
annotations as well:
@RunWith(PowerMockRunner.class)
@PrepareForTest({MockLibraryOne.class})
public class SomeUnitTest {
...
}
@PrepareForTest({Foo.class,Bar.class})
public class MockLibraryOne {
...
}
}
So in this the @PrepareForTest
annotation on SomeUnitTest
would find MockLibraryOne
, and the @PrepareForTest
annotation there would drag in Foo.class
and Bar.class
as well.
So perhaps writing my own test runner to replace PowerMockRunner
may be a solution.
Or perhaps there's a simpler solution, using PowerMockAgent
class, for example?
edit: Mock Policies may be one solution: https://code.google.com/p/powermock/wiki/MockPolicies
edit: Mock Policies works with PowerMockRunner
but not (it seems) with PowerMockRule
(which I sometimes require due to class loader issues).
Perhaps you're looking for a mock policy?