繁体   English   中英

如何对没有参数的void方法进行单元测试

[英]How to unit test a void method with no arguments

我需要测试一个类,以确定在给定某个输入的情况下是否发生了相关操作。 代码如下:

protected static void receiveInput() {
    String command;
    boolean b = true;
    Scanner scanner = new Scanner(System.in);

    while (b) {

        command = scanner.next();
        switch(command) {

            case "first":
                System.out.println("First!");
                break;

            case "second":
                System.out.println("Second!");
                break;

            case "third":
                System.out.println("Third!");
                break;

            default:
                System.out.println("\n***** Invalid *****\n"); 
        }

        System.out.println("\n");
    }

    scanner.close();
}

如果我能以某种方式控制命令字符串并跟踪扫描仪对象,我可能会得到一个非常彻底的单元测试。 出于某种原因,我实际上不允许将这两个对象注入此方法的参数。 以不同的方式进行此测试有哪些选择?

这是使功能更易测试的完美示例。 该功能不需要输入,不产生输出,仅通过副作用影响世界,通过标准方式使其完全不可测试。

要重构此函数以使其更易于测试:

  • 不要让用户通过扫描仪输入,将用户输入作为输入参数。
  • 不打印结果,返回。

然后,函数的调用者可以决定如何提供输入以及如何处理输出。 您修改的程序可以请求用户输入,调用该函数,然后打印输出。 测试框架可以提供输入列表中的输入以进行测试,并根据预期值检查输出。

除了MattPutnam的优秀答案之外,您的方法还有两个具体的提示。

1.改变返回的字符串

protected static string receiveInput(String arg) {
    String result;
    String command = arg;
    boolean b = true;

    while (b) {
        switch(command) {

            case "first":
                result = "first";
                break;

            case "second":
                result = "second";
                break;

            case "third":
                result = "third";
                break;

            default:
                result = "\n ****Invalid*** \n"; 
        }
    }
    return result;
}

我的偏好只是测试boolean b是否为真。 如果这是真的,你知道它有效,如果没有,它没有。 编辑:请注意,这可能很危险,因为您不会检查arg符合字符串条件,而是它有一个可接受的答案。

关于你要测试当前方法的唯一方法是以某种方式捕获流,因为MattPutnam在评论中回答。

您可以使用http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#setIn(java.io.InputStream)来修改System.in并从文件或ByteArrayInputStream中读取。

以同样的方式,使用http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#setOut(java.io.PrintStream)重定向输出流。

您可以使用系统规则库测试输出。

public class YourTest {
  @Rule
  public SystemOutRule log = new SystemOutRule().enableLog();
  @Rule
  public TextFromStandardInputStream systemInMock = emptyStandardInputStream();

  @Test
  public void test() {
    systemInMock.provideLines("first", "second");
    ... //execute your code
    assertEquals("First!\nSecond!\n", log.getLogWithNormalizedLineSeparator());
  }
}

完全披露:我是系统规则的作者。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM