Replacing PowerMock's @PrepareForTest programmatically?

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).

Answers


Why do you even want to mock static methods? Why not wrap those static methods in a class that you can mock with mockito?

class FooWraper {
   void someMethod() {
     Foo.someStaticMethod()
   }
}

and then you can create a mock of your FooWraper. No need to use Powermock at all...


Perhaps you're looking for a mock policy?


Need Your Help

Whats better to use in C++11 , Zero or NULL?

c++ pointers c++11

Nowadays, with C++11, Whats recommended to use, Zero or NULL? The first of the second if?

What does enumerable mean?

javascript enumerable

I was directed to MDN's for..in page when it said, "for..in Iterates over the enumerable properties of an object."