PowerMock Static Spy
Code Example
See PowerMock Setup page to learn how to get started with PowerMock.
UnderTest.java1| package main; 2| 3| public class UnderTest { 4| public void foo() { 5| MockClass.foo(); 6| System.out.println("UnderTest!"); 7| MockClass.foo2(); 8| } 9| }MockClass.java
1 | package main; 2 | 4 | public class MockClass { 5 | public static void foo() { 6 | System.out.println("Mocked Method!"); 7 | } 9 | 10| public static void foo2() { 11| System.out.println("foo2!"); 12| } 13| }StaticSpyTest.java
1 | package test; 2 | import main.*; 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.powermock.api.mockito.PowerMockito; 6 | import org.powermock.core.classloader.annotations.PrepareForTest; 7 | import org.powermock.modules.junit4.PowerMockRunner; 8 | 9 | @PrepareForTest(MockClass.class) 10| @RunWith(PowerMockRunner.class) 11| public class StaticSpyTest { 12| @Test 13| public void spyTest() { 14| // Object under test 15| UnderTest obj = new UnderTest(); 16| 17| // Partial mock 18| PowerMockito.spy(MockClass.class); 19| PowerMockito.doNothing().when(MockClass.class); 20| MockClass.foo(); 21| 22| // Test 23| obj.foo(); 24| } 25| }Console Output
UnderTest! foo2!
Similar to the Static Mock post, the MockClass.java class is mocked, but only partially. MockClass.foo() is mocked, which is why the "Mocked Method!" is not displayed, but "foo2!" is displayed from MockClass.foo2() (UnderTest.java line 7).
The PowerMockito method calls (StaticSpyTest.java lines 18-19) that perform the partial mock are not so straightforward as they are with Mockito. Line 18 tells PowerMock that MockClass.java needs to be treated as a partial mock, and line 19 tells it to mock a specific method in MockClass.class. The additional line (line 20) specifies the specific static method to mock, which is not needed in Mockito, and can cause confusion to those unfamiliar with PowerMock.
Static Method Stub
What happens if the mocked method returns something? Similar to Mockito, PowerMock supports stubs, which are controlled return variables.
Referring to the same Code Example as above, with a few modifications, we can see how static method stubs work.
MockedClass.java1| package main; 2| 3| public class MockClass { 4| public static String foo() { 5| return "Mocked Value!"; 6| } 7| }
The String "Mocked Value!" will not actually be returned.
UnderTest.java1| package main; 2| 3| public class UnderTest { 4| public String foo() { 5| return MockClass.foo(); 6| } 7| }StaticSpyUnderTest.java
1 | package test; 2 | 3 | import main.*; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.powermock.api.mockito.PowerMockito; 8 | import org.powermock.core.classloader.annotations.PrepareForTest; 9 | import org.powermock.modules.junit4.PowerMockRunner; 10| 11| @PrepareForTest(MockClass.class) 12| @RunWith(PowerMockRunner.class) 13| public class StaticSpyTest { 14| @Test 15| public void spyTest() { 16| // Object under test 17| UnderTest obj = new UnderTest(); 18| 19| // Partial mock 20| PowerMockito.spy(MockClass.class); 21| PowerMockito.doReturn("Stub value!").when(MockClass.class); 22| MockClass.foo(); 23| 24| // Test 25| Assert.assertEquals("Stub value!", obj.foo()); 26| } 27| }
The only difference here is that we use doReturn("Stub value!") instead of doNothing(), which tells PowerMock to return a specific value ("Stub value!") when MockClass.foo() is called. After executing this test we see that the test passes, with obj.foo() returning the expected value.
Comments
Post a Comment