使用Console.readline()测试void main的输出

时间:2014-02-07 06:06:02

标签: java junit console mockito

我需要通过输出(在system.out中)对现有代码进行junit测试

public static void main(String args[])
{
   Console console = System.console();
   String str = console.readLine();
   System.out.println("halo"+str);

}

由于console.readline正在等待用户输入,我发现它将在console.readline()中停止,从而阻止我获取输出。

有办法做到这一点吗?使用Mockito或其他东西做它是否可行?

3 个答案:

答案 0 :(得分:2)

几乎不可能测试适用于System.console()的代码,因为System.console()总是在测试中重新调整null。另外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);
}

可以使用System Rules库的System.out规则测试StandardOutputStreamLog的输出。但是在您的代码中,写Console的作者而不是System.out更容易。

答案 1 :(得分:0)

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()));
    }
}

答案 2 :(得分:0)

以下测试将使用JMockit模拟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());
}