На основании ответа @ dfa и другого ответа, показывающего, как тестировать System.in , я хотел бы поделиться своим решением, чтобы дать вход для программы и проверить ее вывод .
Для справки я использую JUnit 4.12.
Допустим, у нас есть эта программа, которая просто копирует ввод в вывод:
import java.util.Scanner;
public class SimpleProgram {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print(scanner.next());
scanner.close();
}
}
Чтобы проверить это, мы можем использовать следующий класс:
import static org.junit.Assert.*;
import java.io.*;
import org.junit.*;
public class SimpleProgramTest {
private final InputStream systemIn = System.in;
private final PrintStream systemOut = System.out;
private ByteArrayInputStream testIn;
private ByteArrayOutputStream testOut;
@Before
public void setUpOutput() {
testOut = new ByteArrayOutputStream();
System.setOut(new PrintStream(testOut));
}
private void provideInput(String data) {
testIn = new ByteArrayInputStream(data.getBytes());
System.setIn(testIn);
}
private String getOutput() {
return testOut.toString();
}
@After
public void restoreSystemInputOutput() {
System.setIn(systemIn);
System.setOut(systemOut);
}
@Test
public void testCase1() {
final String testString = "Hello!";
provideInput(testString);
SimpleProgram.main(new String[0]);
assertEquals(testString, getOutput());
}
}
Я не буду много объяснять, потому что я считаю, что код читабелен, и я привел свои источники.
Когда JUnit запускает testCase1()
, он будет вызывать вспомогательные методы в порядке их появления:
setUpOutput()
, из-за аннотации @Before
1023 *
provideInput(String data)
, вызывается с testCase1()
getOutput()
, вызывается с testCase1()
restoreSystemInputOutput()
, из-за аннотации @After
1035 *
Я не тестировал System.err
, потому что мне это не нужно, но это должно быть легко реализовать, подобно тестированию System.out
.