问题
The Test case I am writing for:
public class AClassUnderTest {
// This test class has a method call
public Long methodUnderTest() {
// Uses the FinalUtilityClass which contains static final method
FinalUtilityClass.myStaticFinalMethod(<3-parameters-here>);
// I want to mock above call so that test case for my "methodUnderTest" passes
}
}
I have one final class.
public final class FinalUtilityClass {
/**
* Method has 3 parameters
*/
public static final MyBean myStaticFinalMethod(<3-parameters-here>) {
}
}
I have already added below code in my test class:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ FinalUtilityClass.class })
I want to write test case for mocking it.
I want to mock the call of myStaticFinalMethod()
so that I can get the expected MyBean
instatnce which I can use in further code to pass my test case.
The <3-parameters-here>
are Calendar, String, String.
I tried doing:
1)
PowerMockito.mock(FinalUtilityClass.class)
PowerMockito.when(FinalUtilityClass.myStaticFinalMethod(<3-parameters-here>).thenReturn(new MyBean());
2)
PowerMockito.mockStatic(FinalUtilityClass.class)
PowerMockito.when(FinalUtilityClass.myStaticFinalMethod(<3-parameters-here>).thenReturn(new MyBean());
3)
PowerMockito.spy(FinalUtilityClass.class)
PowerMockito.when(FinalUtilityClass.myStaticFinalMethod(<3-parameters-here>).thenReturn(new MyBean());
But nothing worked for me. Please suggest what is correct way for mocking static final
method in final
class.
回答1:
The following steps are required to mock calls to static methods:
- Use the
@RunWith(PowerMockRunner.class)
annotation at the class-level of the test case. - Use the
@PrepareForTest(ClassThatContainsStaticMethod.class)
annotation at the class-level of the test case - Use
PowerMock.mockStatic(ClassThatContainsStaticMethod.class)
to mock all methods of this class
When you follow these steps as documented, your tests should work. And as the OP seems to be confused about PowerMock vs. PowerMockito - that is (more or less) the same thing:
PowerMock and PowerMockito are based on the same technology. They just have different "connectors" to either work with EasyMock or Mockito. So, yes the above example says PowerMock.mockStatic()
- but PowerMockito has mockStatic()
methods as well. In that sense: the core things (for example regarding preparation with annotations) are the same. See here for example (they are so close that the linked tutorial says "Intro to PowerMock" - although it does introduce PowerMockito.
And as you seem to not believe me - see this example:
package ghostcat.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
final class ClassWithStatic {
public final static int ignoreMethodCall(String a, String b, int c) {
System.out.println("SHOULD NOT SHOW UP: " + a);
return c;
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassWithStatic.class)
public class MockStaticTest {
@Test
public void test() {
PowerMockito.mockStatic(ClassWithStatic.class);
PowerMockito.when(ClassWithStatic.ignoreMethodCall("a", "b", 5)).thenReturn(42);
org.junit.Assert.assertEquals(ClassWithStatic.ignoreMethodCall("a", "b", 5), 42);
}
}
This test passes; and doesn't print anything. Therefore the final static method gets mocked.
来源:https://stackoverflow.com/questions/45034464/powermock-static-final-method-in-final-class