我写了一个工厂来产生java.sql.Connection对象:
public class MySQLDatabaseConnectionFactory implements DatabaseConnectionFactory {
@Override public Connection getConnection() {
try {
return DriverManager.getConnection(...);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
我想验证传递给DriverManager的参数。getConnection,但我不知道如何模拟静态方法。我的测试用例使用JUnit 4和Mockito。是否有一个好的方法来模拟/验证这个特定的用例?
我也遇到过类似的问题。根据PowerMock的mockStatic文档,接受的答案对我不起作用,直到我做出了更改:@PrepareForTest(classthatcontainsstaticmethod .class)。
我不需要使用BDDMockito。
我的类:
public class SmokeRouteBuilder {
public static String smokeMessageId() {
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
log.error("Exception occurred while fetching localhost address", e);
return UUID.randomUUID().toString();
}
}
}
我的测试类:
@RunWith(PowerMockRunner.class)
@PrepareForTest(SmokeRouteBuilder.class)
public class SmokeRouteBuilderTest {
@Test
public void testSmokeMessageId_exception() throws UnknownHostException {
UUID id = UUID.randomUUID();
mockStatic(InetAddress.class);
mockStatic(UUID.class);
when(InetAddress.getLocalHost()).thenThrow(UnknownHostException.class);
when(UUID.randomUUID()).thenReturn(id);
assertEquals(id.toString(), SmokeRouteBuilder.smokeMessageId());
}
}
你可以做一点重构:
public class MySQLDatabaseConnectionFactory implements DatabaseConnectionFactory {
@Override public Connection getConnection() {
try {
return _getConnection(...some params...);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
//method to forward parameters, enabling mocking, extension, etc
Connection _getConnection(...some params...) throws SQLException {
return DriverManager.getConnection(...some params...);
}
}
然后你可以扩展你的MySQLDatabaseConnectionFactory类来返回一个模拟的连接,对参数进行断言等等。
扩展类可以驻留在测试用例中,如果它位于相同的包中(我鼓励您这样做)
public class MockedConnectionFactory extends MySQLDatabaseConnectionFactory {
Connection _getConnection(...some params...) throws SQLException {
if (some param != something) throw new InvalidParameterException();
//consider mocking some methods with when(yourMock.something()).thenReturn(value)
return Mockito.mock(Connection.class);
}
}