2010-04-08 12 views
65

¿Alguien puede sugerir una manera fácil de obtener una referencia a un archivo como un tipo de objeto String/InputStream/File/etc en una clase de prueba junit? Obviamente, podría pegar el archivo (xml en este caso) como un String gigante o leerlo como un archivo, pero ¿hay un atajo específico para Junit como este?Forma fácil de obtener un archivo de prueba en JUnit

public class MyTestClass{ 

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

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

} 

Respuesta

73

Puede probar la anotación @Rule. Aquí está el ejemplo de los documentos:

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

sólo tiene que crear FileResource clase extiende ExternalResource.

Ejemplo completo

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

¿Podría proporcionar un ejemplo más detallado? Te daría mucho más votos positivos ... – guerda

+2

Acabo de hacerlo para demostrarte que estás equivocado. –

+15

Recién votado con la esperanza de ayudar a demostrar que tiene razón. –

13

Sé que dijo que no desea leer el archivo en la mano, pero esto es bastante fácil

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

Todo lo que tiene que hacer es asegurarse de que el archivo en cuestión se encuentre en el classpath. Si está utilizando Maven, simplemente coloque el archivo en src/test/resources y Maven lo incluirá en el classpath al ejecutar sus pruebas. Si necesita hacer mucho este tipo de cosas, puede poner el código que abre el archivo en una superclase y heredar sus pruebas.

+0

Gracias por decir en realidad dónde el archivo debe estar ubicado, ¡no solo cómo abrirlo! – Vince

66

Si necesita hacer que un objeto File, se puede hacer lo siguiente:

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

que tiene la ventaja de plataformas de trabajo, como se describe en this blog post.

+19

Tomaré las dos líneas frente a los 100 millones de líneas de cualquier día de la semana. –

2

Usted puede intentar hacer:

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

Si desea cargar un archivo de recursos de prueba como una cadena con sólo unas pocas líneas de código y sin ningún tipo de dependencias extra, esto hace el truco:

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" coincide con el inicio de la entrada y solo hay una. Entonces esto analiza el contenido completo del archivo y lo devuelve como una cadena. Lo mejor de todo es que no requiere ninguna biblioteca de terceros (como IOUTils).

Cuestiones relacionadas