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

标签 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'后按回车键应该输出一些东西,按'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);
    }
}

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

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

Text for S

java.lang.NullPointerException
at App.getChar(tree.java:28)
at App.main(tree.java:7)
at TestApp.testMain(TestApp.java:15) <23 internal calls>

所以,看起来它得到了第一个输入('s'),但没有得到第二个...

非常感谢任何帮助。

最佳答案

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

不用说这是一个错误。

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

您还可以构建一个更精细的模拟 System.in 和一个模拟 System.out 并在您检测到对 的调用时用更多输入补充它System.out.println.

关于java - 单元测试多个连续的键盘输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15849978/

相关文章:

java - 安卓(Java): Getting GPS location accuracy

java - 在树莓派上使用OpenCV进行视觉追踪FRC

python:如何模拟辅助方法?

java - 正在使用 Assert.assertTrue(true);并断言 Assert.fail(); JUnit 测试的良好实践?

java - 将 Clob 转换为字符串

Java httppost文件post打印上传速度

java - 如何从 GUI 按钮启动 JUnit @Suite?

java - 如何模拟从类级别对象调用的方法

java - 显式调用 @PostConstruct 注解的方法

java - 在Java中的测试类中实例化要测试的类