Тестирование outputtream.write (<String>) без создания файла - PullRequest
10 голосов
/ 17 февраля 2012

Я тестирую выходной поток в Java, как показано ниже.

    Writer outputStream = getOutputStream(fileName);
    if(outputStream != null) {
        try {
            outputStream.write(inputText);
        }
        finally {
            outputStream.close();
        }
    }
    else {
        throw new IOException("Output stream is null");
    }

Я пишу тест mockito, как показано ниже

public void testFileWrite() throws IOException {
    when(testObj.getOutputStream(outputFileNameValidValue)).thenReturn(outputStreamMock);
    doNothing().when(outputStreamMock).write(Matchers.anyString());
    doNothing().when(bufferedReaderMock).close();

    testObj.write(outputFileNameValidValue, reveredFileInput);

    verify(outputStreamMock).write(Matchers.anyString());
    verify(outputStreamMock).close();
}

Проблема в том, что вы создаете OutputStreamWriter(new FileOutputStream(filename))физический файл на диске создан.

Можем ли мы проверить Outputstream.write без фактической записи файла на диск?

Спасибо, Ананд

Ответы [ 5 ]

12 голосов
/ 17 февраля 2012

Вы можете использовать ByteArrayOutputStream, который записывает данные в память.Вы можете прочитать это с помощью ByteArrayInputStream.

Альтернативой является запись ожидаемого OutputStream, который завершается неудачно, как только вы пытаетесь записать неправильный байт.Это может быть полезно, чтобы точно определить, где / почему тест не пройден.

2 голосов
/ 17 февраля 2012

Вы можете попробовать использовать System.out для вывода, который на самом деле является Printstream, который является подклассом OutputStream

см: http://docs.oracle.com/javase/6/docs/api/java/lang/System.html http://docs.oracle.com/javase/6/docs/api/java/io/PrintStream.html

1 голос
/ 07 марта 2012

Как уже предлагали другие, вы должны иметь возможность вводить фиктивный OutputStream в тестируемый класс.Поскольку вашему тестируемому классу нужен объект OutputStream, который записывает данные в данный файл, вам нужно будет вставить фиктивный OutputStreamFactory в тестируемый класс.

У меня есть для вас этот код, который полностью самодостаточен:

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.io.IOException;
import java.io.OutputStream;

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class Test9328173 {

    private ClassUnderTest testObj;

    @Mock
    private OutputStreamFactory factory;

    @Mock
    private OutputStream stream;

    @Before
    public void setUp() throws Exception {
        testObj = new ClassUnderTest();
        testObj.factory = factory;
    }

    @Test
    public void testFileWrite() throws Exception {
        when(factory.create("filename")).thenReturn(stream);

        testObj.write("filename", new byte[]{1, 2, 3});

        verify(stream).write(new byte[]{1, 2, 3});
        verify(stream).close();
    }

    private class ClassUnderTest {

        private OutputStreamFactory factory;

        public void write(String filename, byte[] content) throws IOException {
            OutputStream stream = factory.create(filename);
            try {
                stream.write(content);
            } finally {
                stream.close();
            }
        }
    }

    private interface OutputStreamFactory {

        OutputStream create(String filename);
    }
}
0 голосов
/ 18 февраля 2012

У вас должно быть смоделированное getOutputStream(String), возвращающее java.io.StringWriter, и тогда вы можете утверждать, что ожидаемый контент был написан.

public void testFileWrite() throws IOException {
    StringWriter writer = new StringWriter();
    when(testObj.getOutputStream(outputFileNameValidValue)).thenReturn(writer);

    testObj.write(outputFileNameValidValue, reveredFileInput);

    assertEquals(reveredFileInput, writer.toString());

    verify(writer).close();
}
0 голосов
/ 17 февраля 2012

Вы должны смоделировать ваше getOutputStream: это должно вернуть объект смоделированного потока вывода. Вызов new FileOutputStream действительно создает файл на диске.

Теоретически вы можете создать макет самой файловой системы, но это намного сложнее.

И BTW if(outputStream != null) является избыточным: поток никогда не может быть нулевым. Если это не может быть создано, метод должен вызвать исключение. Это не C, это Java. :)

...