Burlándose de métodos estáticos con Mockito
He escrito una fábrica para producir java.sql.Connection
objetos:
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?
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?
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>