Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 738
Tom Tresansky Avatar asked Feb 01 '13 16:02

Tom Tresansky


People also ask

Can we mock static methods?

Since static method belongs to the class, there is no way in Mockito to mock static methods. However, we can use PowerMock along with Mockito framework to mock static methods.

Is PowerMock a mocking framework?

PowerMock is an open-source Java framework used for creating a mock object in unit testing. It extends other mocking frameworks such as EasyMock and Mockito to enhance the capabilities.

Can static classes be mocked?

Because there is no instance variable, the class name itself should be used to access the members of a static class. The powerful capabilities of the feature-rich JustMock framework allow you to mock static classes and calls to static members like methods and properties, set expectations and verify results.


2 Answers

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) 
like image 197
zibi Avatar answered Sep 19 '22 19:09

zibi


Though I'm late to the party, but we can achieve partial mocking and override the default behavior of mocked object by explicitly specifying it.

Below example show how we can make PowerMockito to call real methods if behavior isn't defined explicitly:

e.g. PowerMockito.mockStatic(MyClass.class, new CallsRealMethods());

like image 41
Arun Avatar answered Sep 22 '22 19:09

Arun