Why Can't I access src/test/resources in Junit test run with Maven?

前端 未结 3 1455
渐次进展
渐次进展 2021-01-30 20:31

I am having a problems running the following code:

configService.setMainConfig(\"src/test/resources/MainConfig.xml\");

From within a Junit @Bef

相关标签:
3条回答
  • 2021-01-30 21:05

    Access MainConfig.xml directly. The src/test/resources directory contents are placed in the root of your CLASSPATH.

    More precisely: contents of src/test/resources are copied into target/test-classes, so if you have the following project structure:

    .
    └── src
        └── test
            ├── java
            │   └── foo
            │       └── C.java
            └── resources
                ├── a.xml
                └── foo
                    └── b.xml
    

    It will result with the following test CLASSPATH contents:

    • /foo/C.class
    • /a.xml
    • /foo/b.xml

    To actually access the files from Java source, use getClass().getResource("/MainConfig.xml").getFile().

    0 讨论(0)
  • 2021-01-30 21:17

    I guess setMainConfig expects the path of a resource, that it will load using the ClassLoader, and not a relative file path. It would help if you linked to the javadoc of this mysterious configService.setMainConfig method.

    If my guess is correct, then the path should just be MainConfig.xml. Mave copies the contents of src/test/resources to the target/test-classes (IIRC) folder. And this test-classes folder is in the classpath of the unit tests.

    0 讨论(0)
  • 2021-01-30 21:19

    I ran into the same problem today and I have found some solutions.

    First, here is my file structure:

    .
    └── src
    │   └── test
    │       ├── java
    │       │   └── mypackage
    │       │       └── MyClassTest.java
    │       └── resources
    │           └── image.jpg
    └── target
        └── test-classes
                ├── image.jpg
                └── mypackage
                    └── MyClassTest.class  
    

    What is not working: (Java 11 synthax)

    var imgFile = new File("image.jpg"); // I was expecting that Junit could find the file.
    var absPath = file.getAbsolutePath(); // /home/<user>/../<project-root>/image.jpg
    var anyFileUnderThisPath = file.exists(); // false
    

    What we can notice is that the absolute path does not point at all on my image! But if I had an image under at the project-root, then it would have worked.

    Solution 1: Paths (introduced in Java 7)

    var relPath = Paths.get("src", "test", "resources", "image.jpg"); // src/test/resources/image.jgp
    var absPath = relPath.toFile().getAbsolutePath(); // /home/<user>/../<project-root>/src/test/resources/image.jpg
    var anyFileUnderThisPath = new File(absPath).exists(); // true
    

    As we can see, it points on the right file.

    Solution 2: ClassLoader

    var classLoader = getClass().getClassLoader();
    var url = classLoader.getResource("image.jpg"); // file:/home/<user>/../<project-root>/target/test-classes/image.jpg
    var file = new File(url.getFile()); // /home/<user>/../<project-root>/target/test-classes/image.jpg
    var anyFileUnderThisPath = file.exists(); // true
    

    Note that now the file is searched under the target directory! and it works.

    Solution 3: File (Adaptation of the non-working example)

    var absPath = new File("src/test/resources/image.jpg").getAbsolutePath();
    var var anyFileUnderThisPath = new File(absPath).exists(); // true
    

    Which works also after taking the absolute path and putting src/test/resources/ as prefix.

    Summary

    All three solutions works but having to put src/test/resources/ is, in my own opinion not elegant, and this is why I would prefer the 2nd solution (ClassLoader).

    Sources:

    • Read file and resource in junit test
    • Java read a file from resources folder
    0 讨论(0)
提交回复
热议问题