如何在 mockito 中模拟 Class.forName()



我有一个调用Class.forName((的方法。当我创建一个单元测试时,它会抛出ClassNotFoundException。有没有办法模拟 Class.forName(( 行为?

方法需要测试:

public Map<String, Object> invokeOperation(String className, String methodName) {
try {
final Class<?> implClass =
Class.forName(className);
final Object obj= implClass.getDeclaredConstructor().newInstance();
final Class<?>[] parameterTypes = getParamTypes();
final Object[] args = getParamValues();
final Method method = obj.getMethod(methodName, parameterTypes);
final Map<String, Object> result = (Map<String, Object>) method.invoke(obj, args);
return result;
} catch (final ClassNotFoundException | InstantiationException e) {
e.printStackTrace();
}
}

我认为你不应该嘲笑Class.forName方法。

相反,请考虑:

  1. 要在测试中检查的测试创建一个特殊的类,如果您使用的是构建系统(如 maven(,请将其放入src/test/java文件夹中,以便此类不会到达生产工件。这将涵盖一条"快乐之路">

  2. 如果要测试异常,请考虑以下重构(我将包含invokeOperation方法的类称为OperationInvoker(:

public class OperationInvoker {
private ClassByNameResolver classByNameResolver;
public OperationInvoker(ClassByNameResolver classByNameResolver) {
this.classByNameResolver = classByNameResolver;
}
public Map<String, Object> invokeOperation(String className, String methodName) {
try {
final Class<?> implClass = classByNameResolver.resolveClass(className);
final Object obj= implClass.getDeclaredConstructor().newInstance();
final Class<?>[] parameterTypes = getParamTypes();
final Object[] args = getParamValues();
final Method method = obj.getMethod(methodName, parameterTypes);
final Map<String, Object> result = (Map<String, Object>) method.invoke(obj, args);
return result;
} catch (final ClassNotFoundException | InstantiationException e) {
e.printStackTrace();
}
}
}
public class ClassByNameResolver { // or provide an interface and implementation
public Class<?> resolveClass(String name) throws ... {
return Class.forName(name);
}
}

现在,这允许使用mockito轻松模拟ClassByNameResolver以模拟 将引发异常的情况。

这是一个品味问题,但在这种情况下,单元测试可以同时涵盖这两个类(单元=两个类(

Mockito不支持模拟静态方法。如果你真的想这样做,你可以看看PowerMock。

但是,如前所述,更好的方法是根本不嘲笑任何东西。只需将一个真实的、有效的类名(及其方法名(传递给该方法,并测试它是否正常工作。我最好创建一个(或多个类(仅用于测试目的,这样您就不需要在每次更改类时都修复测试。

最新更新