Простий спосіб отримати файл тесту в JUnit


78

Чи може хтось запропонувати простий спосіб отримати посилання на файл як об’єкт типу String / InputStream / File / etc у тестовому класі junit? Очевидно, що я міг вставити файл (xml в даному випадку) у вигляді гігантської рядка або прочитати його як файл, але чи існує ярлик, характерний для Junit, як цей?

public class MyTestClass{

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

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

}

Відповіді:


85

Ви можете спробувати @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();
        }
    }

}


9
Ого. Схоже, це моя найкраща відповідь на даний момент. Я справді погано прогнозую майбутнє.
Ха.

77

Якщо вам потрібно отримати Fileпредмет, ви можете зробити наступне:

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

Що має перевагу роботи на різних платформах, як описано в цьому дописі в блозі .


14

Я знаю, ви сказали, що не хочете читати файл вручну, але це досить легко

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 включить його до шляху до класу під час запуску тестів. Якщо вам потрібно багато робити подібні речі, ви можете помістити код, який відкриває файл, у суперклас і отримати тести, що успадковуються від цього.


Дякуємо, що насправді сказали, де повинен знаходитись файл, а не лише як його відкрити!
Вінс,

1

Ви можете спробувати зробити:

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).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.