单元测试多个连续键盘输入

时间:2013-04-06 10:52:36

标签: java unit-testing junit

我正在尝试对从键盘输入的主要方法进行单元测试。我知道有几个关于测试键盘输入和使用System.setIn(...)这样做的问题,但它只适用于我的第一个输入。

我的代码:

public class TestApp {
    @Test
    public void testMain() {
        InputStream stdin = System.in;
        try {
            System.setIn(new ByteArrayInputStream("s\r\nx\r\n".getBytes()));

            String args[] = {};
            App.main(args);

            // TODO: verify that the output is what I expected it to be
        }
        catch(IOException e) {
            assertTrue("Unexpected exception thrown: " + e.getMessage(), false);
        }
        finally {
            System.setIn(stdin);
        }
    }
}

我想要实现的是输入's'然后输入'x'(两个不同的条目)。

正常使用程序时,按's'后按Enter键输出内容,按'x'后输出其他内容。主要方法如下:

class App {
    public static void main(String[] args) throws IOException {
        int choice;
        do {
            choice = getChar();
            switch(choice) {
                case 's':
                    System.out.println("Text for S");
                    break;
                case 'x':
                    System.out.println("Exiting");
                    break;
            }
        } while(choice != 'x');
    }

    public static String getString() throws IOException {
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(isr);
        String s = br.readLine();
        return s;
    }

    public static char getChar() throws IOException {
        String s = getString();
        return s.charAt(0);
    }
}

注意:我知道实现它的最佳方法是注入InputStream依赖项并使用它而不是System.in,但我无法更改代码。这是我的限制,我无法更改main()getString()getChar()方法。

当我执行测试时,这是输出:

  

S

的文字      

显示java.lang.NullPointerException
    在App.getChar(tree.java:28)
    在App.main(tree.java:7)
    在TestApp.testMain(TestApp.java:15)< 23内部调用>

所以,它看起来像第一个输入('s'),但不是第二个输入......

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

getString方法在每次调用时构造一个新的BufferedReader,它会在System.in返回之前将readLine中的8192个字符读入其缓冲区。这意味着它在第一次调用时读取's'和'x',但仅使用第一行。然后,从方法返回时,BufferedReader被丢弃。在下一次调用时,它构造一个新实例来查找剩余的字符,但是,当System.in已经耗尽时,找不到。

不言而喻,这是一个错误。

一种可能的解决方法是构造一个虚拟InputStream,在初始's'和换行符之后填充最多8k标记,后跟'x'和换行符。

您还可以构建更精细的模拟System.in以及模拟System.out,并在检测到对System.out.println的调用时为其添加更多输入。