PowerkMock-In BufferedReader работает промежуточно
То, что я хочу сделать, это высмеивать недавно созданный экземпляр BufferedReader
, Вот код, который должен быть проверен:
A.java
...
@Override
public String read(String fileName) throws IOException {
...
try {
fileReader = new FileReader(fileName);
bufferedReader = new BufferedReader(fileReader);
String tmp;
StringBuilder builder = new StringBuilder();
while ((tmp = bufferedReader.readLine()) != null) {
builder.append(tmp);
}
return builder.toString();
} catch (IOException e) {
...
} finally {
...
}
}
...
Что я должен сделать, это PowerMock как FileReader
создание и BufferedReader
создание.
ATest.java
@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
public class ATest {
@Mock
private FileReader fileReader;
@Mock
private BufferedReader bufferedReader;
...
@Test
public void test() throws Exception {
PowerMockito.whenNew(FileReader.class).withArguments(FILE_NAME).thenReturn(fileReader);
PowerMockito.whenNew(BufferedReader.class).withAnyArguments().thenReturn(bufferedReader);
PowerMockito.doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) throws Throwable {
return "test";
}
}).when(bufferedReader).readLine();
assertArrayEquals(reader.read(FILE_NAME), new String[]{"test"});
}
}
Но тогда тест никогда не заканчивается. Я даже не могу отладить это.
Как только PowerMockito.doAnswer()
удаляется код выполняется (и доступен для отладки). Я также пытался использовать Mockito.mock()
вместо PowerMockito.doAnswer()
это не помогает
Что может стать причиной прерывания выполнения теста?
2 ответа
Проблема заключалась в том, что мне также пришлось издеваться над ценностью после первого bufferedReader.readLine()
, потому что в противном случае он всегда будет возвращать проверенное значение, таким образом, не завершая.
Mockito.when(bufferedReader.readLine()).thenReturn("first line").thenReturn(null);
НОТА
Хотя это и есть фактический ответ на вопрос, но вы должны строго рассмотреть выбор дизайна, предложенного GhostCat в другом ответе (что я в итоге и сделал).
Просто другая точка зрения: можно сказать, что ваша настоящая проблема в вашем коде - это два вызова new()
для FileReader / BufferedReader.
Что делать, если вы передали Reader для этого метода; вместо строки, обозначающей имя файла?
Что если вы передали "ReaderFactory" в базовый класс, содержащий этот метод read(String)
? (где вы будете использовать внедрение зависимостей, чтобы получить эту фабрику в свой класс)
Тогда: вы будете искать улучшенный дизайн - и вам не нужно будет использовать PowerMock. Вы можете сделать шаг назад и пойти с Mockito или EasyMock; как не было бы больше необходимости издеваться над вызовами new
,
Итак, мой ответ: вы создали сложный для тестирования код. Теперь вы пытаетесь решить проблему дизайна, используя большой (безобразный) молоток PowerMock. Да, это будет работать. Но это всего лишь вторая лучшая альтернатива.
Более разумный вариант - научиться писать тестируемый код (начните здесь, например); и хорошо, напишите тестируемый код. И прекрати использовать PowerMock (я делал это много месяцев назад; после сильной боли, вызванной PowerMock; и я никогда не сожалел об этом решении).