如何在 Maven 和 Intellij 之间处理 Junits 中的相对路径
Posted
技术标签:
【中文标题】如何在 Maven 和 Intellij 之间处理 Junits 中的相对路径【英文标题】:How to deal with relative path in Junits between Maven and Intellij 【发布时间】:2011-08-04 00:16:49 【问题描述】:我有一个带有模块的 maven 项目
/myProject
pom.xml
/myModule
pom.xml
/foo
bar.txt
考虑myModule中的一个Junit,它需要打开bar.txt,maven的basedir就是模块目录。
所以打开文件bar.txt:
new File("foo/bar.txt")
当您在 intellij 中启动相同的 junit 时执行 mvn test
BUT 时,这很有效,因为 Intellij 在项目目录中设置了 basedir,而不是模块目录。
Intellij 尝试打开 myProject/foo/bar.txt
而不是 myProject/myModule/foo/bar.txt
有办法解决吗?
【问题讨论】:
谢谢!这是我的确切问题 【参考方案1】:如果您将项目文件 (.idea) 保存在与源代码相同的目录中,则来自 @tbruyelle 的解决方案有效。如果您选择 Keep Project files in ... 在不同的位置,则 $MODULE_DIR$ 会尝试在工作区目录中查找并且找不到路径。这看起来像是 IntelliJ 上的一个错误,希望他们尽快修复它。
解决方法: 您可以在工作目录中指定maven模块的绝对/相对路径
$MODULE_DIR$/../master/mavenmodule1
$MODULE_DIR$: points to workspace directory
../: relative path to source code
master: root directory of your source code
mavenmodule1: maven module name / directory name of the child module.
对于多模块 maven 项目,您别无选择,您需要有不同的运行配置指向该模块。我希望有另一个变量只指向 $MAVEN_MODULE$ ($MODULE_DIR$/../master/$MAVEN_MODULE$),这样我们就可以对所有模块使用这个配置。对于上面的示例,$MAVEN_MODULE$ 将替换为 mavenmodule1
【讨论】:
【参考方案2】:您可以在运行/调试配置窗口中指定测试运行器的工作目录:
【讨论】:
【参考方案3】:受纪尧姆启发的解决方案:
在Run->Edit configuration->Defaults->JUnit->Working directory
中设置$MODULE_DIR$
的值,Intellij 将像 Maven 一样设置所有junit 中的相对路径。
【讨论】:
完美!你不知道这花费了我和我的团队多少时间,这记录在哪里? 无处可去,但现在新版本的 Intellij 建议MODULE_DIR
文本字段的 MODULE_DIR
值
类加载比文件好得多...使用文件系统是邪恶的
使用文件系统是邪恶的?你认为最终的文件来自哪里???在某些情况下,例如当使用 C.I.服务器,您可能希望指定要在工件中不存在的测试用例中使用的源配置文件。请告诉我我应该如何在不使用邪恶文件系统的情况下与他们联系。谢谢。
请注意,这会改变您的默认 JUnit 启动配置。因此,它不会改变您已经创建的任何配置。如果此解决方案不适合您,请仔细检查您实际使用的配置以及它是否正确继承了此值。【参考方案4】:
如果您想保留您的代码,您可以尝试更改运行/调试配置中的工作目录(组合框中的第一个条目可以访问您要运行的内容) 将此设置为您的模块根目录。 但更喜欢其他建议的方法:
ClassLoader.getSystemResourceAsStream(youPath)
或者我的首选:
getClass.getResource(youPath)
或
getClass.getResourceAsStream(youPath)
路径中的前导“/”表示项目的工作目录,而没有“/”表示当前类的相对目录。
我将最后一个解决方案用于我的测试:我将我的测试数据资源放在与测试源相同的包级别,或者放在子目录中以避免过于混乱的包。
这样我可以进行简单的调用,无需复杂的路径,也无需处理工作目录:
project-root
- module A
- src
- test
- rootfile.txt
- my-complicated-package-naming-root
- mypackage
- Test.java
- testResource.xml
我可以通过这种方式获取文件:
final URL rootfile= Test.class.getResource("/rootfile.txt");
final URL testResource= Test.class.getResource("testResource.xml");
【讨论】:
我将 junit 工作目录设置为 $MODULE_DIR$ 并且它按预期工作。不幸的是,在默认的 junit 配置中不能使用这个变量!真可惜…… $MODULE_DIR$ 在默认的 junit 配置中不建议使用,但您可以强制“工作配置”字段中的值 avec 它有效! @iangreen:你真的确定是这样吗?你介意引用文档吗?【参考方案5】:a) 不要使用文件,使用 InputStreams。通过
获取您的InputStream
ClassLoader.getSystemResourceAsStream("foo/bar.xml")
大多数处理文件的 API 也对 InputStreams 感到满意。
b) 不要使用 foo
目录,使用 maven 和您的 IDE 都知道的目录(即将它们放在 src/main/resources
或 src/test/resources
中,因此它们位于类路径中)
c) 如果您的 API 绝对需要 File
,而不是 InputStream
,您仍然可以这样做
new File(ClassLoader.getSystemResource("foo/bar.xml").toURI())
【讨论】:
如果您在项目中使用 groovy,请小心:ClassLoader.getSystemResourceAsStream 可能会停止工作(始终返回 null),因为 intellij 开始使用命令行包装器/动态代理。请参阅禁用此功能jguru.com/faq/view.jsp?EID=1533847。我已经浪费了很多时间试图弄清楚发生了什么...... 谢谢我知道这些东西,但我需要检索一个不能在类路径中的文件,因为它的路径是在某些参数中配置的。我真的需要一个相对路径的解决方案。以上是关于如何在 Maven 和 Intellij 之间处理 Junits 中的相对路径的主要内容,如果未能解决你的问题,请参考以下文章
intellij Project make 和 Maven Compile 之间的区别?
如何在 IntelliJ IDEA 中创建 JavaFX Maven 项目?