Java 如何在mockito中模拟Class.forName()
我有一个方法在其中调用Class.forName()。当我创建一个单元测试时,它抛出ClassNotFoundException。有没有办法模拟Class.forName()行为 需要测试的方法:Java 如何在mockito中模拟Class.forName(),java,unit-testing,mockito,Java,Unit Testing,Mockito,我有一个方法在其中调用Class.forName()。当我创建一个单元测试时,它抛出ClassNotFoundException。有没有办法模拟Class.forName()行为 需要测试的方法: publicmap调用操作(stringclassname,stringmethodname){ 试一试{ 期末班= Class.forName(className); 最终对象obj=implClass.getDeclaredConstructor().newInstance(); 最终类[]par
publicmap调用操作(stringclassname,stringmethodname){
试一试{
期末班=
Class.forName(className);
最终对象obj=implClass.getDeclaredConstructor().newInstance();
最终类[]parameterTypes=getParamTypes();
最终对象[]args=getParamValues();
最终方法=obj.getMethod(方法名,参数类型);
最终映射结果=(Map)方法.invoke(obj,args);
返回结果;
}捕获(最终类NotFoundException |实例化异常e){
e、 printStackTrace();
}
}
Mockito模拟静态方法。如果你真的想做,你可以看看
但是,正如前面提到的,更好的方法是不要嘲笑任何东西。只需将真实有效的类名(及其方法名)传递给该方法,并测试其工作是否正常。我还建议创建一个(或多个)仅用于测试目的的类,这样您就不必在每次更改类时修复测试。我认为您不应该模拟
类.forName
方法
相反,请考虑:
src/test/java
文件夹中,以便该类不会到达生产工件。这将涵盖一条“快乐之路”公共类操作入口{
私有ClassByNameResolver ClassByNameResolver;
公共操作调用器(ClassByNameResolver ClassByNameResolver){
this.classByNameResolver=classByNameResolver;
}
公共映射调用操作(字符串类名称、字符串方法名称){
试一试{
最终类implClass=classbynamesolver.resolveClass(className);
最终对象obj=implClass.getDeclaredConstructor().newInstance();
最终类[]parameterTypes=getParamTypes();
最终对象[]args=getParamValues();
最终方法=obj.getMethod(方法名,参数类型);
最终映射结果=(Map)方法.invoke(obj,args);
返回结果;
}捕获(最终类NotFoundException |实例化异常e){
e、 printStackTrace();
}
}
}
公共类ClassByNameResolver{//或提供接口和实现
公共类resolveClass(字符串名称)引发{
返回Class.forName(name);
}
}
现在,这允许使用mockito轻松模拟classbynamesolver
,以模拟
将抛出异常的情况
这是一个品味问题,但是在这种情况下,单元测试可以同时覆盖这两个类(unit=two Class)为什么要尝试模拟Class.forName(),而不是在测试中简单地传递一个有效的、现有的类名?
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);
}
}