2010-04-08 67 views
65

有人可以建议一个简单的方法来获得一个文件的引用作为一个String/InputStream /文件/ etc类型的对象在junit测试类吗?很明显,我可以将文件(在这种情况下是xml)粘贴为一个巨大的字符串,或者将它作为文件读取,但是有没有特定于Junit的快捷方式?简单的方法来获得一个测试文件到JUnit

public class MyTestClass{ 

@Resource(path="something.xml") 
File myTestFile; 

@Test 
public void toSomeTest(){ 
... 
} 

} 

回答

73

您可以尝试@Rule注释。下面是从文档的例子:

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); 
    } 
} 

你只需要创建FileResource类扩展ExternalResource

完整的例子

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(); 
     } 
    } 

} 

+3

你能提供一个更详细的例子吗?它会给你很多upvotes ... – guerda 2010-04-08 06:08:50

+2

只是做了它来证明你错了。 – 2010-04-08 16:57:35

+15

只是为了帮助证明他是正确的。 – 2010-04-08 21:49:16

13

我知道你说你不想读用手文件,但这是很容易

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()); 
    } 
} 

您所要做的就是确保相关文件位于类路径中。如果您使用Maven,只需将该文件放在src/test/resources中,Maven将在运行测试时将其包含在类路径中。如果你需要做很多这样的事情,你可以把打开文件的代码放在一个超类中,并让你的测试继承它。

+0

谢谢你真的说在哪里该文件应该位于,不仅如何打开它! – Vince 2017-06-13 12:27:04

66

如果你需要真正得到一个File对象,你可以做到以下几点:

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

其中有工作的跨平台的好处,如this blog post描述。

+19

我会在这一周的任何一天采取两条线与1亿条线。 – 2014-03-21 00:10:57

2

你可以尝试做:

String myResource = IOUtils.toString(this.getClass().getResourceAsStream("yourfile.xml")).replace("\n",""); 
1

如果要加载测试资源文件与代码,没有任何额外的依赖只是几行字符串,这样做的伎俩:

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”匹配输入的开始,并且只有一次。因此,它会解析整个文件内容并将其作为字符串返回。最重要的是,它不需要任何第三方库(如IOUTils)。

相关问题