web-dev-qa-db-fra.com

Un moyen facile d’obtenir un fichier de test dans JUnit

Quelqu'un peut-il suggérer un moyen simple d'obtenir une référence à un fichier sous la forme d'un objet de type String/InputStream/File/etc. dans une classe de test Junit? Évidemment, je pourrais coller le fichier (XML dans ce cas) sous forme de chaîne géante ou le lire sous forme de fichier, mais existe-t-il un raccourci spécifique à Junit comme celui-ci?

public class MyTestClass{

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

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

}
75
benstpierre

Tu peux essayer @Rule annotation. 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);
    }
}

Il vous suffit de créer FileResource classe en prolongeant 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();
        }
    }

}
81
Ha.

Si vous devez réellement obtenir un objet File, vous pouvez procéder comme suit:

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

Qui a l’avantage de travailler sur plusieurs plates-formes, comme décrit dans cet article de blog .

76
slashnick

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, mettez simplement le fichier dans src/test/resources et Maven l'inclura dans le chemin d'accès aux classes lors de l'exécution de vos tests. Si vous devez beaucoup faire ce genre de chose, vous pouvez mettre le code qui ouvre le fichier dans une super-classe et en faire hériter vos tests.

14
Joey Gibson

Si vous souhaitez charger un fichier de ressources de test sous forme de chaîne avec seulement quelques lignes de code et sans aucune dépendance supplémentaire, procédez comme suit:

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 la saisie et il n'y en a qu'une. Donc, cela analyse tout le contenu du fichier et le renvoie sous forme de chaîne. Mieux encore, il ne nécessite aucune bibliothèque tierce (comme IOUTils).

1
gMale

Vous pouvez essayer de faire:

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