2012-08-13 145 views
0

我目前正在研究JUnit测试,该测试检查负责从/向某个文件加载/保存进程配置的功能。考虑到资源中存在特定的配置文件,该功能从文件加载参数。否则,该功能会尝试创建新的配置文件并保留在该类中编码的默认配置。现在我正在使用.class.getResource()方法来检查配置文件是否存在,并检索必要的信息。从maven的“测试类”和“类”目录中证明这种方法工作正常。但是,当文件不存在时尝试保存默认配置时,我遇到了问题,即.class.getResource()方法返回null,因为资源尚不存在。这阻止我建立目标资源目录(依赖于上下文)来保存文件。在java maven项目中获取当前工作资源目录

有没有一种方法来编写我的功能来评估特定对象是作为测试执行还是在生产中执行?更确切地说,如何根据执行模式建立一个指向资源文件的相对路径,以指向生产资源(../ classes/...)或测试资源(../test-classes/ ..)该项目目前是哪个?

我的问题有点类似于下面的How should I discover test-resource files in a Maven-managed Java project?,但我认为它不足以保证新的线程。

回答

0

如果我理解你是正确的,本质上你的问题是你有一个Maven项目,它读取一个特定的文件(通常和单元测试期间),它决定了应用程序的行为。如果该文件不存在,您的应用程序将创建它。

ClassLoader.getSystemResource(...)的问题在于它实际上并未扫描单个目录。相反,它正在研究Java的类路径以确定该特定资源的位置。如果类路径中有多个目录,则它将具有文件可能位于的多个区域。

从某种意义上说,.getSystemResource(...)是一种方法。您可以查找文件的位置,但不能获取放置文件的适当位置。

* 那么当你需要把文件放在正确的位置时呢? *

你有两个基本选择:

  1. 硬编码的文件的位置:没有人喜欢这样做。
  2. 在类路径上扫描的位置传递到类加载器。例如,您可以使用第一个并在那里创建文件。

第二个选项实际上并不是一个坏的;看看这个示例代码。

final Enumeration<URL> urls = ClassLoader.getSystemClassLoader().getResources(""); 
    if(! urls.hasMoreElements()) { 
     LOG.error("No entries exist on the class path!"); 
     System.exit(1); 
    } 
    final File configFile = new File(urls.nextElement().getFile(), "config.xml"); 
    configFile.createNewFile(); 
    LOG.info("Create a new configuration file: " + configFile.getPath()); 
    System.exit(0); 

这解决了配置文件是我的目标文件夹中:..\target\classes\config.xml

给你你做什么;乐意提供更多提示&建议,如果你觉得更多是必需的。

+0

如果您觉得答案可以解决您的问题,请相应标记。 :) – 2012-08-13 23:28:50

0

这听起来像你要做到以下几点:

当你的代码运行时,它会尝试加载配置文件。当找不到配置文件时,您需要创建配置文件。转折是,

  • 如果您正在执行的代码中的“生产模式”(我猜使用的东西等,这取决于你的代码的性质EXEC-Maven的插件或码头,Maven的插件)你想配置文件放置在$ {project.build.outputDirectory}

  • 如果您在“测试模式”下执行代码(例如通过surefire或failsafe),您希望将配置文件放置在$ {project .build.testOutputDirectory}

我会do是使用ServiceLoader模式。

您创建一个负责存储配置的ConfigFileStore接口。

的ConfigFileStoreFactory枚举所有实现该接口(使用ServiceLoader通过API获得所有/META-INF/services/com.yourpackage.ConfigFileStore资源和提取这些类名的服务。如果有注册没有实现再它将基于getClass()实例化一个将文件存储在路径中的默认实现(例如,向后工作以获得$ {project.build.outputDirectory}注意,它应该处理类被捆绑到JAR中的情况,并且我会假设在这种情况下,配置文件可能会被存储在JAR附近)

注意:默认实现不会在中注册/ META-INF /服务

然后将src/test/java下您扩展默认实现并注册中的src /测试/资源/ META-INF /服务,延长执行/ com.yourpackage.ConfigFileStore

现在,当运行在类路径上具有测试代码的代码,将会找到测试版本,它将从$ {project.build.testOutputDirectory}中为类获取getClass(),因为它来自测试类路径的/ META-INF /服务。

当运行没有类路径的测试代码代码,默认的实现将搭载的getClass()的一类从$ {} project.build.outputDirectory

应该做你想要什么。