ankushbbbr
ankushbbbr

Reputation: 923

PowerMockito mockStatic with input

I need to mock a static method which has an input argument. For other functions in the class, original methods must get called and for the function I'm trying to mock, only the mocked stub must be executed. I tried the following code but it is not working as expected.

public class Foo {
    public static String static1() {
        System.out.println("static1 called");
        return "1";
    }

    public static String static2() {
        System.out.println("static2 called");
        return "2";
    }

    public static String staticInput(int i) {
        System.out.println("staticInput called");
        return "static " + i;
    }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest({Foo.class })
public class TestMockito {

    @Test
    public void test() throws Exception {

        PowerMockito.mockStatic(Foo.class, Mockito.CALLS_REAL_METHODS);
        PowerMockito.doReturn("dummy").when(Foo.class ,"static1");

        PowerMockito.when(Foo.staticInput(anyInt())).thenAnswer(invocation -> {
            System.out.println((int)invocation.getArgument(0));
            return "staticInput mock";
        });


        //        PowerMockito.doAnswer(new Answer() {
        //            @Override
        //            public Object answer(InvocationOnMock invocation) throws Throwable {
        //                int i = (int) invocation.getArguments()[0];
        //                System.out.println(i);
        //                return i;
        //            }
        //
        //        }).when(Foo.staticInput(anyInt()));

        System.out.println(Foo.static1());
        System.out.println(Foo.static2());
        System.out.println(Foo.staticInput(7));
    }
}

I'm getting the following output:

staticInput called  
dummy 
static2 called  
2 
staticInput called  
static 7

Upvotes: 0

Views: 909

Answers (1)

Lesiak
Lesiak

Reputation: 25966

The cleanest code I come up with was to to explicitely mark methods that shoud be forwarded to their real implementation.

PowerMockito.mockStatic(Foo.class);
PowerMockito.doReturn("dummy").when(Foo.class, "static1");
PowerMockito.when(Foo.static2()).thenCallRealMethod();
PowerMockito.when(Foo.staticInput(anyInt())).thenAnswer(invocation -> {
    System.out.println((int)invocation.getArgument(0));
    return "staticInput mock";
});

Output (matches my expectations):

dummy
static2 called
2
7
staticInput mock

Strangly, my output from the orginal code differs from your output (and shows that the static method with an input param is mocked.):

staticInput called
dummy
static2 called
2
7
staticInput mock

I still believe that the version I proposed is better: real static methods are not called when setting up the mock, which unfortunately happens with your code.

Upvotes: 1

Related Questions