Java 在涉及Console.readline()的情况下测试void main的输出
我需要通过输出(in system.out)junit测试现有代码 由于console.readline正在等待用户输入,我发现它将在console.readline()中停止,从而阻止我获取输出Java 在涉及Console.readline()的情况下测试void main的输出,java,junit,console,mockito,Java,Junit,Console,Mockito,我需要通过输出(in system.out)junit测试现有代码 由于console.readline正在等待用户输入,我发现它将在console.readline()中停止,从而阻止我获取输出 有办法做到这一点吗?是否可以使用Mockito或其他方法进行测试?对于单元测试来说,main方法不是一个很好的候选方法。它只是一个应用程序的入口点。也许,您需要将类重构为某种依赖注入。例如: public class Something { private final LinesProvid
有办法做到这一点吗?是否可以使用Mockito或其他方法进行测试?对于单元测试来说,
main
方法不是一个很好的候选方法。它只是一个应用程序的入口点。也许,您需要将类重构为某种依赖注入。例如:
public class Something {
private final LinesProvider linesProvider;
public Something(LinesProvider linesProvider) {
this.linesProvider = linesProvider;
}
public void sayHello() {
String str = linesProvider.readLine();
System.out.println("halo "+str);
}
public static void main(String args[]) {
new Something(new LinesProvider() {
private final Console console = System.console();
@Override
public String readLine() {
return console.readLine();
}
}).sayHello();
}
}
interface LinesProvider {
String readLine();
}
然后,您可以测试系统输出,如下所示,尽管这不是一个好的实践。相反,尝试将I/O逻辑与应用程序逻辑分开:
public class TestSomething {
private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
private PrintStream printStream = new PrintStream(outputStream, true);
@Before
public void setUp() {
System.setOut(printStream);
}
@Test
public void test() {
new Something(new LinesProvider() {
@Override
public String readLine() {
return "Vasya";
}
}).sayHello();
assertEquals("halo Vasya" + System.getProperty("line.separator"), new String(outputStream.toByteArray()));
}
}
测试与
System.console()
一起工作的代码几乎是不可能的,因为您在测试中总是重新运行System.console()
。另外,Console
是没有公共构造函数的最终类
我建议与Console
的编写者和读者一起工作,并测试与编写者和读者一起工作的代码
public static void main(String args[]) {
Console console = System.console();
BufferedReader reader = new BufferedReader(console.reader());
main2(reader, console.writer(), args);
}
static void main2(BufferedReader reader, Writer writer, String args[] {
String str = reader.readline();
System.out.println("halo"+str);
}
可以使用库的
StandardOutputStreamLog
规则测试输出到System.out
。但是在您的代码中,写入控制台的编写器要比写入系统容易得多。out
使用JMockit mocking API,以下测试将起作用:
@Test
public void testMyApp(@Mocked final Console console)
{
new NonStrictExpectations(System.class) {{
System.console(); result = console;
console.readLine(); result = " test";
}};
OutputStream output = new ByteArrayOutputStream();
System.setOut(new PrintStream(output));
MyApp.main(new String[0]);
String lineSep = System.getProperty("line.separator");
assertEquals("halo test" + lineSep, output.toString());
}
@Test
public void testMyApp(@Mocked final Console console)
{
new NonStrictExpectations(System.class) {{
System.console(); result = console;
console.readLine(); result = " test";
}};
OutputStream output = new ByteArrayOutputStream();
System.setOut(new PrintStream(output));
MyApp.main(new String[0]);
String lineSep = System.getProperty("line.separator");
assertEquals("halo test" + lineSep, output.toString());
}