我写了一个工厂来产生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。是否有一个好的方法来模拟/验证这个特定的用例?
观察:当您在静态实体中调用静态方法时,您需要更改@PrepareForTest中的类。
例如:
securityAlgo = MessageDigest.getInstance(SECURITY_ALGORITHM);
对于上面的代码,如果您需要模拟MessageDigest类,请使用
@PrepareForTest(MessageDigest.class)
而如果你有如下内容:
public class CustomObjectRule {
object = DatatypeConverter.printHexBinary(MessageDigest.getInstance(SECURITY_ALGORITHM)
.digest(message.getBytes(ENCODING)));
}
然后,您需要准备这个代码所在的类。
@PrepareForTest(CustomObjectRule.class)
然后模拟这个方法:
PowerMockito.mockStatic(MessageDigest.class);
PowerMockito.when(MessageDigest.getInstance(Mockito.anyString()))
.thenThrow(new RuntimeException());
你可以做一点重构:
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);
}
}