使用 Scanner 和 System.in (Java) 对方法进行 Junit 测试

Junit test of method with Scanner and System.in (Java)

我是编程新手,我有这个简单的方法:

public double input() {
        double result = 0;
        Scanner scanner = new Scanner(System.in);
        if (scanner.hasNextDouble()) {
            result = scanner.nextDouble();
        } else {
            System.out.print("Please, type numbers!\n");
        }
        return result;
    }

问题是如何在junit测试中模拟(emulate)用户的键盘输入。

Scanner 作为输入参数传递给要测试的方法。 在您的测试代码中,您可以从字符串创建一个 Scanner 实例:

Scanner scanner = new Scanner("the sample user input");

然后在生产代码中,你可以将new Scanner(System.in)传递给方法。

您应该阅读有关 dependency injection 的更多信息。

Your Class shouldn't be tightly coupled with other classes. Dependencies can be provided to objects at multiple levels according to the need.

  1. Using constructor/setter if it is a field.
  2. Using method parameters if the scope is just in a method.

在你的情况下,只要你说:-

Scanner scanner = new Scanner(System.in);

现在您的代码已与 System.in 流完全耦合。相反,您应该以下面的格式将其作为参数注入到您的方法中。

public double input(InputStream inputStream) {
    double result = 0;
    Scanner scanner = new Scanner(inputStream);
    if (scanner.hasNextDouble()) {
        result = scanner.nextDouble();
    } else {
        System.out.print("Please, type numbers!\n");
    }
    return result;
}

现在您可以从主代码中使用 System.in 调用它。从您的测试 class 中,您可以使用任何 InputStream 调用它。大多数情况下,我们使用 mock/stub 作为它。

注:-以上只是举例,可以根据需要更改。