2010-04-08 4 views
65

Quelqu'un peut-il suggérer un moyen facile d'obtenir une référence à un fichier en tant qu'objet de type String/InputStream/File/etc dans une classe de test junit? Évidemment, je pourrais coller le fichier (xml dans ce cas) dans une chaîne géante ou le lire en tant que fichier mais y a-t-il un raccourci spécifique à Junit comme ça?Un moyen facile d'obtenir un fichier de test dans JUnit

public class MyTestClass{ 

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

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

} 

Répondre

73

Vous pouvez annotation @Rule. Voici l'exemple de la documentation:

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

Vous avez juste besoin de créer FileResource classe extension ExternalResource.

Exemple complet

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

Pourriez-vous fournir un exemple plus détaillé? Cela vous donnerait beaucoup plus de rejets ... – guerda

+2

Juste fait pour vous prouver le contraire. –

+15

Juste upvoted dans l'espoir d'aider à lui prouver le droit. –

13

Je sais que vous avez dit que vous ne vouliez pas lire le fichier à la main, mais c'est assez 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()); 
    } 
} 

Tout ce que vous avez à faire est de vous assurer que le fichier en question est dans le classpath. Si vous utilisez Maven, placez simplement le fichier dans src/test/resources et Maven l'inclura dans le classpath lors de vos tests. Si vous avez souvent besoin de ce genre de chose, vous pouvez placer le code qui ouvre le fichier dans une superclasse et en hériter vos tests.

+0

Merci d'avoir dit où le fichier devrait être situé, non seulement comment l'ouvrir! – Vince

66

Si vous avez besoin pour obtenir réellement un objet File, vous pouvez effectuer les opérations suivantes:

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

Ce qui a l'avantage de la plate-forme de croix de travail, comme décrit dans this blog post.

+19

Je prendrai les deux lignes par rapport aux 100 millions de lignes de n'importe quel jour de la semaine. –

2

Vous pouvez essayer de faire:

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

Si vous voulez charger un fichier de ressources de test en tant que chaîne avec seulement quelques lignes de code et sans dépendances supplémentaires, cela ne l'astuce:

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" correspond au début de l'entrée et il n'y en a qu'un seul. Donc, cela analyse le contenu entier du fichier et le renvoie sous forme de chaîne. Le meilleur de tous, il ne nécessite pas de bibliothèques tierces (comme IOUTils).