我正在为一个需要在初始化期间加载配置文件的项目创建一个 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测试用例中运行时,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()返回的对象与之前的调用this.getClass().getResourceAsStream()(为了比较值而保留的调用)完全相同(相同的id)!!!
这里发生了什么?!
为什么直接调用该方法不起作用,而在其中插入一个新的方法调用起作用呢?
老实说,我对此感到非常惊讶。
顺便提一下,我正在使用JUnit版本4.10。它可能以某种方式篡改了getClassLoader调用吗?
非常感谢,
Carles
src/test/resources/
是 Eclipse 中的源文件夹吗? - Sotirios Delimanolis