Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 723
Kumar Avatar asked Sep 11 '20 04:09

Kumar


People also ask

Can we mock static methods in Mockito?

Since static method belongs to the class, there is no way in Mockito to mock static methods.

How do you mock a private static method?

For Mockito, there is no direct support to mock private and static methods. In order to test private methods, you will need to refactor the code to change the access to protected (or package) and you will have to avoid static/final methods.

Can static classes be mocked?

Because there is no instance variable, the class name itself should be used to access the members of a static class. The powerful capabilities of the feature-rich JustMock framework allow you to mock static classes and calls to static members like methods and properties, set expectations and verify results.


1 Answers

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 there is an open issue, in particular check this comment.

like image 126
Marc Avatar answered Oct 16 '22 17:10

Marc