How to deal with the relative path in Junits between Maven and Intellij

I have a maven project with module

/myProject pom.xml /myModule pom.xml /foo bar.txt 

Consider Junit in myModule, which needs to open bar.txt, and maven is the module directory.

So, to open the bar.txt file:

  new File("foo/bar.txt") 

This works well when you run mvn test BUT when you run the same junit in intellij , it fails because Intellij installs baseir in the project directory, not the module.

Intellij tries to open myProject/foo/bar.txt instead of myProject/myModule/foo/bar.txt

Is there any way to handle this?

+42
java intellij-idea junit maven-2
Apr 12 '11 at 15:31
source share
5 answers

If you want to save your code, you can try changing the working directory in the startup / debugging configuration (the first entry in the list box that provides access to what you want to run) Install this in your root module. But prefer the other approach suggested:

 ClassLoader.getSystemResourceAsStream(youPath) 

Or my preference:

 getClass.getResource(youPath) 

or

 getClass.getResourceAsStream(youPath) 

The leading "/" in the path indicates the working directory of your project, and "/" indicates the relative directory in the current class.

I use this latest solution for my tests: I put my test data resources at the same package level as the test source, or in a subdirectory to avoid a too dirty package.

This way I can make a simple call without a complicated path and not have to deal with the working directory:

 project-root - module A - src - test - rootfile.txt - my-complicated-package-naming-root - mypackage - Test.java - testResource.xml 

I can get the files this way:

 final URL rootfile= Test.class.getResource("/rootfile.txt"); final URL testResource= Test.class.getResource("testResource.xml"); 
+25
Apr 12 2018-11-11T00:
source share

Guillaume-inspired solution:

In Run->Edit configuration->Defaults->JUnit->Working directory set the value to $MODULE_DIR$ , and Intellij will set the relative path in all junits just like Maven.

+84
Apr 12 '11 at 16:50
source share

a) Do not use Files, use InputStreams. get InputStream through

 ClassLoader.getSystemResourceAsStream("foo/bar.xml") 

Most of the APIs that work with files are also happy with InputStreams.

b) Do not use foo directories, use directories that both maven and your IDE are aware of (i.e. put them in src/main/resources or src/test/resources , so they are on the class path)

c) If you have an API that File absolutely needs, not InputStream , you can still

 new File(ClassLoader.getSystemResource("foo/bar.xml").toURI()) 
+12
Apr 12 '11 at 15:38
source share

You can specify the working directory for the test runner in the Run / Debug Configurations window:

enter image description here

+1
Mar 16 '17 at 17:26
source share

The solution from @tbruyelle works if you save the project files (.idea) in the same directory as the source code. If you select Save project files to ... in another place, then $ MODULE_DIR $ tries to find in the workspace directory, and the paths cannot be found. This seems like a bug in IntelliJ, hope they fix it soon.

Workaround: You can specify the absolute / relative path of the maven module in the working directory

 $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. 

For a project with multiple maven modules, you have no choice, you need to have different launch configurations pointing to this module. I'm sorry that there is another variable that only points to $ MAVEN_MODULE $ ($ MODULE_DIR $ / .. / master / $ MAVEN_MODULE $), so we can use this configuration for all modules. In the above example, $ MAVEN_MODULE $ will be replaced by mavenmodule1

0
Oct 06 '17 at 15:55 on
source share



All Articles