我写了一个工厂来产生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。是否有一个好的方法来模拟/验证这个特定的用例?
避免使用无法避免的静态方法的典型策略是创建包装对象并使用包装对象。
包装器对象成为真正静态类的外观,您不需要测试它们。
包装器对象可以是这样的
public class Slf4jMdcWrapper {
public static final Slf4jMdcWrapper SINGLETON = new Slf4jMdcWrapper();
public String myApisToTheSaticMethodsInSlf4jMdcStaticUtilityClass() {
return MDC.getWhateverIWant();
}
}
最后,被测试的类可以通过以下方式使用这个单例对象,例如:
在现实生活中使用默认构造函数:
public class SomeClassUnderTest {
final Slf4jMdcWrapper myMockableObject;
/** constructor used by CDI or whatever real life use case */
public myClassUnderTestContructor() {
this.myMockableObject = Slf4jMdcWrapper.SINGLETON;
}
/** constructor used in tests*/
myClassUnderTestContructor(Slf4jMdcWrapper myMock) {
this.myMockableObject = myMock;
}
}
这里您有一个可以很容易测试的类,因为您不直接使用带有静态方法的类。
如果您正在使用CDI,并且可以使用@Inject注释,那么就更容易了。
只需将Wrapper bean设置为@ApplicationScoped,将它作为协作器注入(甚至不需要复杂的构造函数进行测试),然后继续模拟。