Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在mockito中模拟Class.forName()_Java_Unit Testing_Mockito - Fatal编程技术网

Java 如何在mockito中模拟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

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

需要测试的方法:

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
方法

相反,请考虑:

  • 为要在测试中检查的测试创建一个特殊的类,如果您使用的是构建系统(如maven),则将其放入
    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);
       }
    }