Resource files not found from JUnit test cases
Asked Answered
I

7

70

Summary

My JUnit tests are not finding the files they require during execution. I'm using Maven for dependency management and compilation.

Details

All files required by the test cases are located in: src/test/resources.

For example, src/test/resources/resourceFile.txt.

To access a resource I use the following code:

URL url = getClass().getResource("/resourceFile.txt").getFile();
File file = new File(url);

But then file.exists() returns false. And the error I get is:

Tests in error: 
  myJUnitTestCase(tests.MyJUnitTestClass): /home/me/workspace/Project%20Name/target/test-classes/resourceFile.txt (No such file or directory)

Note, the following gives the same error (notice the removed / prefix):

URL url = getClass().getClassLoader().getResource("resourceFile.txt").getFile();
File file = new File(url);

It seems as though the files from src/test/resources are not getting copied into target/test-classes.

Any ideas?

The following questions did not help

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

Loading Properties File In JUnit @BeforeClass

How to deal with the test data in Junit?

Software Versions

Ubuntu 12.04

Apache Maven 2.2.1

Java 1.7.0

Eclipse (Java EE IDE for Web Developers) Indigo Service Release 2

(truncated) Maven POM

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.groupId</groupId>
    <artifactId>artifactId</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>name</name>
    <build>
        <finalName>name</finalName>
        <directory>target</directory>
        <outputDirectory>target/classes</outputDirectory>
        <testOutputDirectory>target/test-classes</testOutputDirectory>
        <sourceDirectory>src/main/java</sourceDirectory>
        <testSourceDirectory>src/test/java</testSourceDirectory>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <directory>src/test/resources</directory>
            </testResource>
        </testResources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
Iniquitous answered 10/5, 2012 at 14:28 Comment(5)
It seems as though the files from src/test/resources are not getting copied into target/test-classes Did you actually verify that?Solarium
No, I am an idiot... sorry. I just checked and I can confirm that they ARE actually copied there. Maybe it's due to the "%20" in the path?Iniquitous
Are you trying to open an input stream from that file? If so, you may use the following directly to do this (instead of using URL): .class.getClassLoader().getResourceAsStream(fileName)Chlamydate
I'm trying to open it as a File. My solution is now: org.apache.commons.io.FileUtils.toFile(myClass().getResource("resourceFile.txt"));Iniquitous
It certainly might be the space (%20) in the path, that can lead to any kinds of trouble ;)Solarium
I
46

My mistake, the resource files WERE actually copied to target/test-classes. The problem seemed to be due to spaces in my project name, e.g. Project%20Name.

I'm now loading the file as follows and it works:

org.apache.commons.io.FileUtils.toFile(myClass().getResource("resourceFile.txt")‌​);

Or, (taken from Java: how to get a File from an escaped URL?) this may be better (no dependency on Apache Commons):

myClass().getResource("resourceFile.txt")‌​.toURI();
Iniquitous answered 11/5, 2012 at 8:49 Comment(4)
In fact, this question answers that: #2166539Kapok
I also saw in this in target file path there was an escape character in complete path (%20), So, I changed the path of my project to a new location without any space. And it started working like a charm. Basically problem was JUnit was looking for a file in a different location due to escape character and leading to most of the test cases failure.Nolen
Worked with small change>> FileUtils.toFile(myClass().getClassLoader().getResource("resourceFile.txt")‌​);Mystery
can someone clarify what is myClass() means? I need to get a test json into my test class, but TestClass() instead of myClass() seems to be wrong. So, I don't understand how to properly use this line(Nautilus
H
13

You know that Maven is based on the Convention over Configuration pardigm? so you shouldn't configure things which are the defaults.

All that stuff represents the default in Maven. So best practice is don't define it it's already done.

    <directory>target</directory>
    <outputDirectory>target/classes</outputDirectory>
    <testOutputDirectory>target/test-classes</testOutputDirectory>
    <sourceDirectory>src/main/java</sourceDirectory>
    <testSourceDirectory>src/test/java</testSourceDirectory>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
    </resources>
    <testResources>
        <testResource>
            <directory>src/test/resources</directory>
        </testResource>
    </testResources>
Hazen answered 10/5, 2012 at 18:53 Comment(3)
thanks for the tip. the reason I added it is because I'm quite inexperienced with Maven so I wanted to make things explicit (remove the magic)... but I'll remove the unnecessary configuration in future.Iniquitous
are you sure the behaviour requested by @AlexAverbuch is really the default in mvn ?Insist
If you are using Tycho and eclipse-plugin as packaging type, don't forget to aadd src/test/resources in build.properties file.Hurds
V
1

This is actually redundant except in cases where you want to override the defaults. All of these settings are implied defaults.

You can verify that by checking your effective POM using this command

mvn help:effective-pom

    <finalName>name</finalName>
    <directory>target</directory>
    <outputDirectory>target/classes</outputDirectory>
    <testOutputDirectory>target/test-classes</testOutputDirectory>
    <sourceDirectory>src/main/java</sourceDirectory>
    <testSourceDirectory>src/test/java</testSourceDirectory>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
    </resources>
    <testResources>
        <testResource>
            <directory>src/test/resources</directory>
        </testResource>
    </testResources>

For example, if i want to point to a different test resource path or resource path you should use this otherwise you don't.

    <resources>
        <resource>
            <directory>/home/josh/desktop/app_resources</directory>
        </resource>
    </resources>
    <testResources>
        <testResource>
            <directory>/home/josh/desktop/test_resources</directory>
        </testResource>
    </testResources>
Voltz answered 9/11, 2017 at 3:59 Comment(0)
A
0

Main classes should be under src/main/java
and
test classes should be under src/test/java

If all in the correct places and still main classes are not accessible then
Right click project => Maven => Update Project
Hope so this will resolve the issue

Annoying answered 5/7, 2019 at 15:58 Comment(0)
M
0

The test Resource files(src/test/resources) are loaded to target/test-classes sub folder. So we can use the below code to load the test resource files.

String resource = "sample.txt";
File file = new File(getClass().getClassLoader().getResource(resource).getFile());

System.out.println(file.getAbsolutePath());

Note : Here the sample.txt file should be placed under src/test/resources folder.

For more details refer options_to_load_test_resources

Mungovan answered 4/2, 2020 at 15:21 Comment(0)
L
0

You may have defined:

<packaging>pom</packaging>

If you did this, the resources won't be present in the target directory when you will launch your tests. And mvn package won't create it either.

At the contrary, if you define:

<packaging>jar</packaging>

Or nothing as the default value is jar. As Maven is based on Convention over Configuration. You will end up with:

  • src/main/resources => target/classes
  • src/test/resources => target/test-classes
Lengthy answered 9/11, 2021 at 10:4 Comment(0)
T
-2

Make 'maven.test.skip' as false in pom file, while building project test reource will come under test-classes.

<maven.test.skip>false</maven.test.skip>

Tumbrel answered 23/10, 2020 at 12:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.