2010-04-08 9 views
65

Qualcuno può suggerire un modo semplice per ottenere un riferimento a un file come oggetto di tipo String/InputStream/File/etc in una classe di test junit? Ovviamente potrei incollare il file (xml in questo caso) come una stringa gigante o leggerlo come un file ma c'è una scorciatoia specifica per Junit come questa?Un modo semplice per ottenere un file di test in JUnit

public class MyTestClass{ 

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

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

} 

risposta

73

È possibile provare l'annotazione @Rule. Ecco l'esempio dalla documentazione:

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

Hai solo bisogno di creare FileResource classe che estende ExternalResource.

Esempio completa

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

Potrebbe fornire un esempio più dettagliato? Ti darebbe molti più voti ... – guerda

+2

Ho appena fatto per dimostrare che hai torto. –

+15

Appena svalutato nella speranza di aiutare a dimostrarlo nel modo giusto. –

13

So che hai detto che non volevi leggere il file in mano, ma questo è abbastanza facile

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

Tutto ciò che dovete fare è assicurarsi che il file in questione si trovi nel classpath. Se utilizzi Maven, inserisci il file in src/test/resources e Maven lo includerà nel classpath durante l'esecuzione dei test. Se hai bisogno di fare questo genere di cose molto, puoi inserire il codice che apre il file in una superclasse e che i tuoi test ereditano da esso.

+0

Grazie per aver detto dove il file dovrebbe essere localizzato, non solo come aprirlo! – Vince

66

Se avete bisogno di ottenere in realtà un oggetto File, si potrebbe procedere come segue:

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

che ha il vantaggio di multi-piattaforma di lavoro, come descritto in this blog post.

+19

Prenderò le due linee contro i 100 milioni di linee ogni giorno della settimana. –

2

Si può provare a fare:

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

Se si desidera caricare un file di risorse di test come una stringa con solo poche righe di codice e senza dipendenze in più, questo fa il trucco:

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" corrisponde all'inizio di input e ce n'è sempre uno solo. Quindi questo analizza l'intero contenuto del file e lo restituisce come una stringa. Meglio di tutto, non richiede alcuna libreria di terze parti (come IOUTils).

Problemi correlati