Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.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类?_Java_Testing_Classloader - Fatal编程技术网

我可以吗;替换“;静态代码之外的Java类?

我可以吗;替换“;静态代码之外的Java类?,java,testing,classloader,Java,Testing,Classloader,我有一个要测试的应用程序: import foo.ExtClass; public class App { public static void main(String[] args) { ExtClass ext = new ExtClass(); ... } } 我想为这个应用程序编写一个单元测试,但是我不想使用foo.ExtClass,而是为这个类使用另一个模拟实现 通常,我会使用工厂根据一些可以在单元测试中控制的配置来实例化类。 但是,在这种情况下,我无法修

我有一个要测试的应用程序:

import foo.ExtClass;
public class App {
  public static void main(String[] args) {
     ExtClass ext = new ExtClass();
     ...
  }
}
我想为这个应用程序编写一个单元测试,但是我不想使用foo.ExtClass,而是为这个类使用另一个模拟实现

通常,我会使用工厂根据一些可以在单元测试中控制的配置来实例化类。 但是,在这种情况下,我无法修改已测试的应用程序


我正在考虑编写一个自定义类加载器来加载模拟类,而不是实际类-不确定在不修改测试应用程序的情况下是否可以加载,以及如何加载。

作为一个选项,您可以使用自定义类加载器,它将用测试类替代您的类。因此,基本上,类加载器不会从应用程序包中加载
ExtClass
,而是使用模拟实现从测试包中加载相同的类

以下是一个例子:


还有非常有用的教程:

我最后使用的方法: 用foo.ExtClass的模拟实现创建了一个单独的项目, 以及单元测试


这样,模拟实现在实际实现之前出现在类路径中,而原始(已测试)项目保持不变。

如果您使用JUnit或其他方法为测试创建一个新类,您只需使用该类中所需的实现实例化
ExtClass
。您可以使用Java框架反射从类加载器的路径加载任何Java类。可以在类中请求可用的方法,甚至可以使用类型正确的参数调用方法。Java Reflection有几个在线教程。如果你jar你的
foo.ExtClass
版本,并把它放在类路径规范的前面(即
Java-cp'ExtClass.jar:original.jar'..
),类加载器应该在原始版本之前自动获取你的版本,并因此对其进行阴影处理。但是,如果您的应用程序已经在运行,这将不起作用。如果原始类以前由应用程序加载程序加载,则没有取消或重新加载它的选项。这仅适用于自定义加载程序(假设它们遵循正确的传播模型)。