Resource files not found from JUnit test cases

JavaUnit TestingMavenJunitResourcebundle

Java Problem Overview


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

https://stackoverflow.com/questions/7613359/why-cant-i-access-src-test-resources-in-junit-test-run-with-maven

https://stackoverflow.com/questions/9983426/loading-properties-file-in-junit-beforeclass

https://stackoverflow.com/questions/2948861/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>

Java Solutions


Solution 1 - Java

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 https://stackoverflow.com/questions/2166039/java-how-to-get-a-file-from-an-escaped-url) this may be better (no dependency on Apache Commons):

myClass().getResource("resourceFile.txt")‌​.toURI();

Solution 2 - Java

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>

Solution 3 - Java

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>

Solution 4 - Java

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

Solution 5 - Java

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

Solution 6 - Java

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

false

Solution 7 - Java

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlex AverbuchView Question on Stackoverflow
Solution 1 - JavaAlex AverbuchView Answer on Stackoverflow
Solution 2 - JavakhmarbaiseView Answer on Stackoverflow
Solution 3 - JavatheyCallMeJunView Answer on Stackoverflow
Solution 4 - JavaG RView Answer on Stackoverflow
Solution 5 - JavaManjunath H MView Answer on Stackoverflow
Solution 6 - Javauser14506669View Answer on Stackoverflow
Solution 7 - JavaNicolas DupouyView Answer on Stackoverflow