JUnit:如何模拟 System.in 测试?
2022-08-31 15:22:35
我有一个Java命令行程序。我想创建JUnit测试用例,以便能够模拟。因为当我的程序运行时,它将进入while循环并等待用户的输入。如何在 JUnit 中模拟它?System.in
谢谢
我有一个Java命令行程序。我想创建JUnit测试用例,以便能够模拟。因为当我的程序运行时,它将进入while循环并等待用户的输入。如何在 JUnit 中模拟它?System.in
谢谢
从技术上讲,可以切换 ,但一般来说,在代码中不直接调用它,而是添加一个间接层,以便从应用程序中的某个点控制输入源会更可靠。确切地说,你如何做到这一点是一个实现细节 - 依赖注入的建议很好,但你不一定需要引入第三方框架;例如,您可以从调用代码传递 I/O 上下文。System.in
如何切换 :System.in
String data = "Hello, World!\r\n";
InputStream stdin = System.in;
try {
System.setIn(new ByteArrayInputStream(data.getBytes()));
Scanner scanner = new Scanner(System.in);
System.out.println(scanner.nextLine());
} finally {
System.setIn(stdin);
}
基于@McDowell的答案和另一个显示如何测试System.out的答案,我想分享我的解决方案,为程序提供输入并测试其输出。
作为参考,我使用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
provideInput(String data)
,调用自testCase1()
getOutput()
,调用自testCase1()
restoreSystemInputOutput()
,因为注解@After
我没有测试,因为我不需要它,但它应该很容易实现,类似于测试。System.err
System.out