我正在为需要在初始化期间加载配置文件的项目创建一个 JUnit 测试用例。
此配置文件位于项目中的 src/main/resources/config 文件夹中,并且在构建 maven 期间将其放入 JAR 内的 /config 文件夹中。
初始化类使用以下语句从那里读取文件:
ClassLoader classloader = this.getClass().getClassLoader();
BufferedReader xmlSource = new BufferedReader(new InputStreamReader(classLoader.getResourceAsStream("/config/config.xml")));
我遇到的问题是,当我将这个 jar 部署并执行到应用程序服务器中时,它会按预期工作,但是,每当我在 Eclipse 的 JUnit TestCase 中运行它时,getResrouceAsStream 方法都会返回 null。
考虑到该类是 my.package.MyClassTest.java,并且它位于 src/test/java/my/package/MyClassTest.java 中,我已经尝试将 config.xml 文件的副本放入以下文件夹但没有成功:
- src/test/resources/config
- src/test/resources/my/package/config
- src/test/java/my/package/config
我知道在 StackOverflow 中已经多次询问过类似的问题,但我发现的所有回复都是指更改文件的加载方式,虽然更改代码可能是一种选择,但我更愿意找到合适的位置该文件,所以我不需要修改已经在生产环境中工作的东西。
那么,我应该把这个文件放在哪里才能在我的 JUnit 测试中使用它呢?
更新
我只是想出了对代码稍作改动的解决方案:我没有使用 ClassLoader 来获取资源,而是直接使用了该类:
Class clazz = this.getClass();
BufferedReader xmlSource = new BufferedReader(new InputStreamReader(clazz.getResourceAsStream("/config/config.xml")));
它从 src/test/resources/config/config.xml 成功读取文件。
但是,这里有一些非常奇怪的东西: Class.getResourceAsStream 方法是:
public InputStream getResourceAsStream(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResourceAsStream(name);
}
return cl.getResourceAsStream(name);
}
如果我调试它,我可以清楚地看到这个getClassLoader0()返回与前一个调用完全相同的对象(相同的 id),this.getClass().getResourceAsStream()(我维护它,只是为了比较值)! !!
这里发生了什么?!
为什么直接调用方法不起作用,而在工作之间插入新的方法调用?
老实说,我真的很惊讶在这面前。
顺便说一句,我使用的是 JUnit 4.10 版。它可能会以某种方式篡改 getClassLoader 调用吗?
非常感谢,
卡尔斯