Search code examples
javaunit-testingmockito

How to mock just one static method in a class using Mockito?


The following line seems to mock all static methods in the class:

MockedStatic <Sample> sampleMock = Mockito.mockStatic( Sample.class );
sampleMock.when( () -> Sample.sampleStaticMethod( Mockito.any( String.class ) ) ).thenReturn( "response" );

Is it possible to mock just one static method in a class?

Edit: the suggested similar question is not similar to this question since the accepted answer there involves using the Power Mockito library and the answers are for mocking all methods in the class, not just one.


Solution

  • By default all methods are mocked. However, using Mockito.CALLS_REAL_METHODS you can configure the mock to actually trigger the real methods excluding only one.

    For example given the class Sample:

    class Sample{
        static String method1(String s) {
            return s;
        }
        static String method2(String s) {
            return s;
        }
    }
    

    If we want to mock only method1:

    @Test
    public void singleStaticMethodTest(){
        try (MockedStatic<Sample> mocked = Mockito.mockStatic(Sample.class,Mockito.CALLS_REAL_METHODS)) {
            mocked.when(() -> Sample.method1(anyString())).thenReturn("bar");
            assertEquals("bar", Sample.method1("foo")); // mocked
            assertEquals("foo", Sample.method2("foo")); // not mocked
        }
    }
    

    Be aware that the real Sample.method1() will still be called. From Mockito.CALLS_REAL_METHODS docs:

    This implementation can be helpful when working with legacy code. When this implementation is used, unstubbed methods will delegate to the real implementation. This is a way to create a partial mock object that calls real methods by default. ...

    Note 1: Stubbing partial mocks using when(mock.getSomething()).thenReturn(fakeValue) syntax will call the real method. For partial mock it's recommended to use doReturn syntax.

    So if you don't want to trigger the stubbed static method at all, the solution would be to use the syntax doReturn (as the doc suggests) but for static methods is still not supported:

    @Test
    public void singleStaticMethodTest() {
        try (MockedStatic<Sample> mocked = Mockito.mockStatic(Sample.class,Mockito.CALLS_REAL_METHODS)) {
            doReturn("bar").when(mocked).method1(anyString()); // Compilation error!
            //...
        }
    }
    

    About this check this issue.