Proper way to access file resources in junit tests
As I was refactoring some JUnit tests recently I was reminded of an important fact on the proper way to read in a file.
In maven any file under /src/test/resources
is automatically copied over to /target/test-classes
. So for example lets say I need to read in a wsdl in my test. So I place the wsdl in the resources folder: /src/test/resources/test.wsdl
. Now at first it might be tempting to reference the file with the following code:
File testWsdl = new File("/src/test/resources/test.wsdl");
and this will actually work on a windows machine; but what about linux, cygwin, or even solaris. Your next improvement might be to replace the '/'
with File.separator
:
File testWsdl = new File(File.separator + "src" + File.separator + "test"
+ File.separator + "resources" + File.separator + "test.wsdl");
This still isn't the best solution which is presented below:
URL url = this.getClass().getResource("/test.wsdl");
File testWsdl = new File(url.getFile());
Using the class's resource will locate the file in the test's classpath, which happens to be /target/test-classes
. And this final solution will work on windows, linux, cygwin, and solaris.
16 comments:
Hammer, meet the head of the nail.
James,
I really appreciate you posting this. I have been scouring the net looking for the way to reference a resource through the maven build. It was working in Eclipse, but it did not work through the maven build.
Thanks for helping me solve this one.
FYI,
To accomplish this in a Groovy Test that extends GroovyTestCase I had to replace the reference to 'this' to the current class.
Instead of:
URL url = this.getClass().getResource("/test.wsdl");
in groovy would be
def url = new DriverTest().getClass().getResource("/test.wsdl")
Where DriverTest is the actually test class.
Hello James, when I googled this as the first entry on the first try to find a solution I thought: Wow! this can't be this easy! Alas, it does not work. I am very surprised because as you say a so-called: resources directory gets special treatment in Maven. And, sure-enough the so-called: test file is copied to test-classes. I have even tried to use new File("../../../../"+filename) since the test file is exactly four directory levels above the test class packaging. I have done something similar with a Maven resources directory for my war file resources using getResourceAsStream() which does work. Any ideas of how to debug this? Please advise, David.
Thank you, this is perfect. I saw a similar article talking about using getResourceAsStream but I needed a path instead.
One note:
I had a lot of trouble getting this to work before I realized that the URL replaces spaces with %20; the File created from such a path (if it's local on your machine) will not work like that! So I ended up doing the following rather circuitous route:
URL url = this.getClass().getResource(CBT_COA1);
String pathWithoutPercents = url.getFile().replace("%20", " ");
File f = new File(pathWithoutPercents);
Spring has some handy utils so you don't have that spaces problem:
ResourceUtils.getFile(this.getClass().getResource("/filename.txt"))
Very usefuke, thanks!
Nice work - thanks a lot
Thank you
Thank you very much!
T.Hanks, to favorites.
Got this to work in groovy when I couldn't get anything else to work:
this.getClass().getResourceAsStream("/test.xml").text
Thanks! It really helped me a lot!
Thank you!
can someone give me an example how can I write a Junit class for WSDL classes or webservice classes
I love you
Post a Comment