What is the best way to mock a static method using Mockito?

What is the best way to mock a static method using Mockito?

I’ve written a factory to produce java.sql.Connection objects:

public class MySQLDatabaseConnectionFactory implements DatabaseConnectionFactory {

    @Override 
    public Connection getConnection() {
        try {
            return DriverManager.getConnection(...);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

I want to validate the parameters passed to DriverManager.getConnection, but since it’s a static method, I don’t know how to mock it. I’m using JUnit 4 and mockito mock static method for testing. What is the best approach for this use case?

The best way to mock static methods in JUnit 4 with Mockito is to use Mockito’s inline mock maker. This feature is available starting from Mockito 3.x, so you should make sure you’re using the correct version. First, you’ll need to enable the mock maker by adding this dependency in your pom.xml:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>3.x.x</version>
    <scope>test</scope>
</dependency>

Once that’s set up, you can mock the static method with Mockito.mockStatic:

import org.mockito.Mockito;
import static org.mockito.Mockito.*;

public class MySQLDatabaseConnectionFactoryTest {

    @Test
    public void testGetConnection() throws SQLException {
        // Mock static DriverManager
        try (MockedStatic<DriverManager> mockedDriverManager = mockStatic(DriverManager.class)) {
            Connection mockConnection = mock(Connection.class);
            mockedDriverManager.when(() -> DriverManager.getConnection(anyString(), anyString(), anyString()))
                               .thenReturn(mockConnection);

            MySQLDatabaseConnectionFactory factory = new MySQLDatabaseConnectionFactory();
            Connection conn = factory.getConnection();

            // Verify that getConnection was called with correct parameters
            mockedDriverManager.verify(() -> DriverManager.getConnection(eq("jdbc:mysql://localhost:3306/db"), eq("user"), eq("password")));
            assertNotNull(conn);
        }
    }
}

By using mockStatic, we can mock the static method, validate the parameters, and assert the connection behavior. This solution works well if you’re using Mockito 3.x or later.

I agree with @macy-davis , but if you’re using an older version of Mockito or if you prefer not to switch, you can use PowerMockito to mock static methods. PowerMockito is an extension of Mockito that allows you to mock static methods, final methods, and even constructors.

Here’s how you could use PowerMockito with your example: 1 . First, add the PowerMockito dependency to your pom.xml:

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito2</artifactId>
    <version>2.x.x</version>
    <scope>test</scope>
</dependency>
  1. Then, you can mock the static method as follows:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import static org.mockito.Mockito.*;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
public class MySQLDatabaseConnectionFactoryTest {

    @Test
    public void testGetConnection() throws Exception {
        // Mock the static DriverManager.getConnection method
        PowerMockito.mockStatic(DriverManager.class);
        Connection mockConnection = mock(Connection.class);
        PowerMockito.when(DriverManager.getConnection(anyString(), anyString(), anyString()))
                    .thenReturn(mockConnection);

        MySQLDatabaseConnectionFactory factory = new MySQLDatabaseConnectionFactory();
        Connection conn = factory.getConnection();

        // Verify that getConnection was called with the correct parameters
        PowerMockito.verifyStatic(DriverManager.class);
        DriverManager.getConnection(eq("jdbc:mysql://localhost:3306/db"), eq("user"), eq("password"));
    }
}

PowerMockito lets you mock static methods easily, and it integrates well with JUnit 4. However, it’s worth noting that PowerMockito can add overhead and is not as widely recommended for general use in newer projects compared to Mockito’s inline mock maker.

Both approaches are great, but to add to what @vindhya.rddy and @macy-davis mentioned:

While Mockito’s inline mock maker is the preferred and modern solution (and I recommend going with that if possible), PowerMockito can still be useful in legacy projects or situations where upgrading Mockito isn’t feasible.

Just a small note on mock validation—if you need to validate the parameters that are passed into DriverManager.getConnection, you can use verify() to ensure the right parameters are used. In Mockito, it’s straightforward with the inline mock maker, and I would always suggest trying to stick with the most modern tools when possible.