Easy way to get test file in JUnit

Can someone suggest an easy way to get a link to a file as an object of type String / InputStream / File / etc in the junit test class? Obviously, I could insert the file (in this case xml) as a giant string or read it as a file, but is there a Junit-specific shortcut like this?

public class MyTestClass{ @Resource(path="something.xml") File myTestFile; @Test public void toSomeTest(){ ... } } 
+63
java unit-testing junit junit4
Apr 08 2018-10-10T00:
source share
5 answers

You can try the @Rule annotation. Here is an example from the docs:

 public static class UsesExternalResource { Server myServer = new Server(); @Rule public ExternalResource resource = new ExternalResource() { @Override protected void before() throws Throwable { myServer.connect(); }; @Override protected void after() { myServer.disconnect(); }; }; @Test public void testFoo() { new Client().run(myServer); } } 

You just need to create a FileResource class that extends ExternalResource .

Full example

 import static org.junit.Assert.*; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExternalResource; public class TestSomething { @Rule public ResourceFile res = new ResourceFile("/res.txt"); @Test public void test() throws Exception { assertTrue(res.getContent().length() > 0); assertTrue(res.getFile().exists()); } } 



 import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; import org.junit.rules.ExternalResource; public class ResourceFile extends ExternalResource { String res; File file = null; InputStream stream; public ResourceFile(String res) { this.res = res; } public File getFile() throws IOException { if (file == null) { createFile(); } return file; } public InputStream getInputStream() { return stream; } public InputStream createInputStream() { return getClass().getResourceAsStream(res); } public String getContent() throws IOException { return getContent("utf-8"); } public String getContent(String charSet) throws IOException { InputStreamReader reader = new InputStreamReader(createInputStream(), Charset.forName(charSet)); char[] tmp = new char[4096]; StringBuilder b = new StringBuilder(); try { while (true) { int len = reader.read(tmp); if (len < 0) { break; } b.append(tmp, 0, len); } reader.close(); } finally { reader.close(); } return b.toString(); } @Override protected void before() throws Throwable { super.before(); stream = getClass().getResourceAsStream(res); } @Override protected void after() { try { stream.close(); } catch (IOException e) { // ignore } if (file != null) { file.delete(); } super.after(); } private void createFile() throws IOException { file = new File(".",res); InputStream stream = getClass().getResourceAsStream(res); try { file.createNewFile(); FileOutputStream ostream = null; try { ostream = new FileOutputStream(file); byte[] buffer = new byte[4096]; while (true) { int len = stream.read(buffer); if (len < 0) { break; } ostream.write(buffer, 0, len); } } finally { if (ostream != null) { ostream.close(); } } } finally { stream.close(); } } } 

+72
Apr 08 '10 at 5:44
source share

If you really need a File object, you can do the following:

 URL url = this.getClass().getResource("/test.wsdl"); File testWsdl = new File(url.getFile()); 

What is the use of cross-platform, as described in this blog post .

+63
Dec 19 '12 at 13:27
source share

I know that you said that you do not want to read the file manually, but it is quite easy.

 public class FooTest { private BufferedReader in = null; @Before public void setup() throws IOException { in = new BufferedReader( new InputStreamReader(getClass().getResourceAsStream("/data.txt"))); } @After public void teardown() throws IOException { if (in != null) { in.close(); } in = null; } @Test public void testFoo() throws IOException { String line = in.readLine(); assertThat(line, notNullValue()); } } 

All you have to do is make sure the file is in the classpath. If you are using Maven, just put the file in src / test / resources and Maven will include it in the classpath when you run your tests. If you need to do a lot of things, you can put code that opens the file in the superclass, and your tests inherit from this.

+13
Apr 08 '10 at 13:53 on
source share

You can try:

 String myResource = IOUtils.toString(this.getClass().getResourceAsStream("yourfile.xml")).replace("\n",""); 
+2
Mar 31 '14 at 19:06
source share

If you want to load a test resource file as a line with several lines of code and without any additional dependencies, this does the trick:

 public String loadResourceAsString(String fileName) throws IOException { Scanner scanner = new Scanner(getClass().getClassLoader().getResourceAsStream(fileName)); String contents = scanner.useDelimiter("\\A").next(); scanner.close(); return contents; } 

"\\ A" corresponds to the beginning of the input and there is only one. Thus, it parses the contents of the entire file and returns it as a string. Best of all, it does not require any third-party libraries (like IOUTils).

+1
Apr 16 '16 at 1:32
source share



All Articles