PowerMock, mock a static method, THEN call real methods on all other statics

Tom Tresansky picture Tom Tresansky · Feb 1, 2013 · Viewed 28k times · Source

I'm setting up mocking a class' static methods. I have to do this in a @Before-annotated JUnit setup method.

My goal is to setup the class to call real methods, except for those methods I explicitly mock.

Basically:

@Before
public void setupStaticUtil() {
  PowerMockito.mockStatic(StaticUtilClass.class);

  // mock out certain methods...
  when(StaticUtilClass.someStaticMethod(anyString())).thenReturn(5); 

  // Now have all OTHER methods call the real implementation???  How do I do this?
}

The problem I'm running into is that within StaticUtilClass the method public static int someStaticMethod(String s) unfortunately throws a RuntimeException if supplied with a null value.

So I can't simply go the obvious route of calling real methods as the default answer as below:

@Before
public void setupStaticUtil() {
  PowerMockito.mockStatic(StaticUtilClass.class, CALLS_REAL_METHODS); // Default to calling real static methods

  // The below call to someStaticMethod() will throw a RuntimeException, as the arg is null!
  // Even though I don't actually want to call the method, I just want to setup a mock result
  when(StaticUtilClass.someStaticMethod(antString())).thenReturn(5); 
}

I need to set the default Answer to call real methods on all other static methods after I mock the results from the method I'm interested in mocking.

Is this possible?

Answer

zibi picture zibi · Feb 1, 2013

What are you looking for is called partial mocking.

In PowerMock you can use mockStaticPartial method.

In PowerMockito you can use stubbing, which will stub only the method defined and leave other unchanged:

PowerMockito.stub(PowerMockito.method(StaticUtilClass.class, "someStaticMethod")).toReturn(5);

also don't forget about the

@PrepareForTest(StaticUtilClass.class)