如何在类路径上模拟属性文件的存在?

Kid*_*rla 6 java junit unit-testing properties mocking

这肯定是一个普遍的问题.我有一个属性文件my-settings.properties,由应用程序类读取.当我编写测试类时,它需要测试可能存在的事物的不同场景,my-settings.properties以确保最大的代码覆盖率(例如,空属性文件,基本属性文件等).但我只能有一个my-settings.properties在我的src/test/resources.

如果只有一些注释,真正伟大的是什么

@MockFileOnClassPath(use = "my-settings-basic.properties", insteadOf = "my-settings.properties")

然后我可以my-settings-XXX.properties在我的文件中有多个文件,/src/test/resources并在每个测试方法上注释正确的文件.但我找不到这样的东西.我正在使用JUnit 4.12.

我可以想到几个粗糙的解决方案:

  1. 在每次测试之前,找到文件系统上的文件,使用文件系统I/O进行复制,然后在测试后再次将其删除.但这很笨拙并且涉及很多冗余.更不用说我甚至不确定类路径目录是否可写.
  2. 使用模拟框架进行模拟 getResource.不知道我会怎么连做,尤其是有100万不同的方式来获取文件(this.getClass().getResourceAsStream(...),MyClass.class.getResourceAsStream(...),ClassLoader.getSystemClassLoader().getResourceAsStream(...)等)

我只是认为这一定是一个常见的问题,也许JUnit,Mockito,PowerMock,EasyMock等已有解决方案?

编辑:有人指出这个问题是重复的为从Eclipse运行的所有JUnit测试指定自定义log4j.properties文件但事实并非如此.那个问题是想要在主调用和测试调用之间有一个不同的属性文件.对我来说,我希望在测试调用和另一个测试调用之间有一个不同的属性文件.

lan*_*ava 3

我发现每当处理文件时,最好引入Resource.

例如:

public interface Resource {
    String getName();
    InputStream getStream();
}
Run Code Online (Sandbox Code Playgroud)

然后你可以通过依赖注入传递资源:

public class MyService {
    private final Properties properties;

    public class MyService(Resource propFile) {
        this.properties = new Properties();
        this.properties.load(propFile.getStream());
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

然后,在您的生产代码中,您可以使用 aClasspathResource或 aFileResourceURLResourceetc,但在测试中您可以使用 aStringResource等。

请注意,如果您使用 spring,您已经实现了这个概念。更多详情请点击这里