0

我目前正在做一个 JUnit 测试,该测试检查负责从/向某个文件加载/保存进程配置的功能。鉴于资源中存在特定的配置文件,该功能会从文件中加载参数。否则,该功能会尝试创建新的配置文件并保留类中编码的默认配置。现在我正在使用 .class.getResource() 方法来检查配置文件是否存在,并检索必要的信息。这种方法被证明在 maven 的“test-class”和“class”目录中都可以正常工作。但是,当文件不存在时,我在尝试保存默认配置时遇到问题,即 .class.getResource() 方法返回 null,因为资源尚不存在。

有没有办法对我的功能进行编码以评估特定对象是作为测试执行还是在生产中执行?更准确地说,我如何构建资源文件的相对路径以指向生产资源(../classes/...)或测试资源(../test-classes/..),具体取决于执行模式目前是哪个项目?

我的问题有点类似于以下如何在 Maven 管理的 Java 项目中发现测试资源文件?但我认为这足以保证新线程的不同。

4

2 回答 2

0

听起来您想要执行以下操作:

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

  • 如果您在“生产模式”下执行代码(我假设使用类似 exec-maven-plugin 或 jetty-maven-plugin 之类的东西,具体取决于代码的性质),您希望将配置文件放在 ${project.构建.输出目录}

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

我要做的是使用 ServiceLoader 模式。

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

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

注意:默认实现不会注册在 /META-INF/services

然后在 src/test/java 中扩展默认实现并在 src/test/resources/META-INF/services/com.yourpackage.ConfigFileStore 中注册该扩展实现

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

当运行在类路径上没有测试代码的代码时,默认实现将从 ${project.build.outputDirectory} 中获取一个类的 getClass()

应该做你想做的。

于 2012-08-14T08:00:11.987 回答
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

由你决定你做什么;如果您觉得需要更多,很乐意提供更多提示和建议。

于 2012-08-13T23:07:46.963 回答