【发布时间】:2013-07-17 18:57:13
【问题描述】:
我正在为需要在初始化期间加载配置文件的项目创建 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 调用?
非常感谢,
卡尔斯
【问题讨论】:
-
src/test/resources/是 Eclipse 中的源文件夹吗? -
@SotiriosDelimanolis 如果您将此作为答案发布,我会投票赞成。
-
@SotiriosDelimanolis:是的。确实,当我查看它时,我意识到 Eclipse 默认将它用于 maven 项目。
标签: java junit classloader getresource