Burlándose de métodos estáticos con Mockito

Resuelto Naftuli Kay asked hace 10 años • 22 respuestas

He escrito una fábrica para producir java.sql.Connectionobjetos:

public class MySQLDatabaseConnectionFactory implements DatabaseConnectionFactory {

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

Me gustaría validar los parámetros pasados DriverManager.getConnection, pero no sé cómo simular un método estático. Estoy usando JUnit 4 y Mockito para mis casos de prueba. ¿Existe una buena manera de simular/verificar este caso de uso específico?

Naftuli Kay avatar Jan 14 '14 10:01 Naftuli Kay
Aceptado

Utilice PowerMockito encima de Mockito.

Código de ejemplo:

@RunWith(PowerMockRunner.class)
@PrepareForTest(DriverManager.class)
public class Mocker {

    @Test
    public void shouldVerifyParameters() throws Exception {

        //given
        PowerMockito.mockStatic(DriverManager.class);
        BDDMockito.given(DriverManager.getConnection(...)).willReturn(...);

        //when
        sut.execute(); // System Under Test (sut)

        //then
        PowerMockito.verifyStatic();
        DriverManager.getConnection(...);

    }

Más información:

  • ¿Por qué Mockito no se burla de los métodos estáticos?
MariuszS avatar Jan 14 '2014 14:01 MariuszS

La burla de métodos estáticos en Mockito es posible desde Mockito 3.4.0. Para más detalles ver:

https://github.com/mockito/mockito/releases/tag/v3.4.0

https://github.com/mockito/mockito/issues/1013

https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#static_mocks

assertEquals("foo", Foo.method());
try (MockedStatic mocked = mockStatic(Foo.class)) {
 mocked.when(Foo::method).thenReturn("bar");
 assertEquals("bar", Foo.method());
 mocked.verify(Foo::method);
}
assertEquals("foo", Foo.method());

En tu caso, algo como esto:

  @Test
  public void testStaticMockWithVerification() throws SQLException {
    try (MockedStatic<DriverManager> dummy = Mockito.mockStatic(DriverManager.class)) {
      DatabaseConnectionFactory factory = new MySQLDatabaseConnectionFactory();
      dummy.when(() -> DriverManager.getConnection("arg1", "arg2", "arg3"))
        .thenReturn(new Connection() {/*...*/});

      factory.getConnection();

      dummy.verify(() -> DriverManager.getConnection(eq("arg1"), eq("arg2"), eq("arg3")));
    }
  }

(Antes de Mockito 5.0.0, burlarse de los métodos estáticos requería una dependencia adicional de mockito-inline)

Para JUnit5 también agregue esto:

<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-junit-jupiter</artifactId>
  <version>${mockito.version}</version>
  <scope>test</scope>
</dependency>
leokom avatar Jul 12 '2020 11:07 leokom