Search code examples
powermockpowermockito

How do I mock a static method call from a nother static method in the same class?


I have a utilities class wherein one static method calls another. I want to mock the called method but not the target method. Does anyone have an example?

I've got:

@RunWith(PowerMockRunner.class)
@PrepareForTest({SubjectUnderTest.class})
public class SubjectUnderTestTest {
...
    SubjectUnderTest testTarget = PowerMockito.mock(SubjectUnderTest.class, Mockito.CALLS_REAL_METHODS);

Solution

  • Starting from the docs, with some minor tweaks, you can either mock or spy the static method, depending on what you need (spying seems a bit less verbose but has different syntax). You can find below a sample for both, based on PowerMockito 1.7.3 & Mockito 1.10.19.

    Given the following simple class with the required 2 static methods:

    public class ClassWithStaticMethods {
    
        public static String doSomething() {
            throw new UnsupportedOperationException("Nope!");
        }
    
        public static String callDoSomething() {
            return doSomething();
        }
    
    }
    

    You can do something like:

    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.powermock.modules.junit4.PowerMockRunner;
    
    import static org.hamcrest.CoreMatchers.is;
    import static org.junit.Assert.assertThat;
    import static org.powermock.api.mockito.PowerMockito.*;
    
    // prep for the magic show
    @RunWith(PowerMockRunner.class)
    @PrepareForTest(ClassWithStaticMethods.class)
    public class ClassWithStaticMethodsTest {
    
        @Test
        public void shouldMockStaticMethod() {
            // enable static mocking
            mockStatic(ClassWithStaticMethods.class);
    
            // mock the desired method
            when(ClassWithStaticMethods.doSomething()).thenReturn("Did something!");
    
            // can't use Mockito.CALLS_REAL_METHODS, so work around it
            when(ClassWithStaticMethods.callDoSomething()).thenCallRealMethod();
    
            // validate results
            assertThat(ClassWithStaticMethods.callDoSomething(), is("Did something!"));
        }
    
        @Test
        public void shouldSpyStaticMethod() throws Exception {
            // enable static spying
            spy(ClassWithStaticMethods.class);
    
            // mock the desired method - pay attention to the different syntax
            doReturn("Did something!").when(ClassWithStaticMethods.class, "doSomething");
    
            // validate
            assertThat(ClassWithStaticMethods.callDoSomething(), is("Did something!"));
        }
    
    }