单元测试-JUnit测试:用户输入



目前正在编写JUnit测试,但在测试依赖用户输入的方法时遇到了困难。有没有一种方法可以在测试方法中"模拟"用户输入?我有这样的东西(我没有粘贴实际的代码,因为方法很长,超出了理解问题的范围;然而,我确实要求用户输入,如果错误,我会再次要求,直到输入正确的值):

   public void method(){
    System.out.println("Enter something");
    int a = scanner.nextInt();
    for(;;){
       if(a!=10){
         System.out.println("Please enter another value!");
         a=sc.nextInt();
       else{
         break;
       }
    }
    //further code
   }

因为这是交互式的,所以很难很好地进行测试,或者至少以可读的方式进行测试。

测试类似代码的一种常见方法是提取一个包含Scanner和PrintWriter的方法,类似于StackOverflow的答案,并测试它:

public void method() {
  method(new Scanner(System.in), System.out);
}
/** For testing. */
public void method(Scanner scanner, PrintWriter output) {
  output.println("Enter something");
  int a = scanner.nextInt();
  // ...
}

这类似于使用System.setIn分配新的stdin/stdout,但更具可预测性,并且需要更少的清理。然而,在这两种情况下,像nextInt这样的方法在等待输入时都会阻塞。除非你想让这个测试成为多线程的(这很复杂),否则你直到最后都无法读取你的输出,你必须提前指定所有的指令:

@Test
public void methodShouldLaunchTheSpaceShuttle() {
  StringWriter output = new StringWriter();
  String input = "5n"        // "Please enter another value!"
               + "10n"       // "Code accepted. Enter command:"
               + "Shuttlen"; // "Launching space shuttle..."
  systemUnderTest.method(new Scanner(input), new PrintWriter(output));
  assertThat(output.toString(), contains("Please enter another value!"));
  assertTrue(systemUnderTest.spaceShuttleLaunched());
}

也就是说,只要你的指令集是简单的(并且不会改变),你就可以添加注释(如上所述),并获得一个有价值的测试,将你的代码覆盖率提高到你需要的程度。

(注意:当然,与其创建重载方法,您还可以将"scanner"one_answers"output"作为系统中的可变字段进行测试。我倾向于尽可能保持类的无状态状态,但如果这对您或您的同事/讲师很重要,那也不是一个很大的让步。)

难道不能提供自己的测试值吗?他们只是int,对吧?如果它们是基元值,您不需要模拟任何东西,只需在给定一组ints:的情况下测试您的功能即可

public void method(){
  int a = // your own test value, or even an array of test values
  for(;;) {
    if (a != 10){
      // check against your test values
    else{
      break;
     }
  }
  //further code
}

如果您依赖外部输入来让单元测试工作,那么这些并不是真正的单元测试。

相关内容

  • 没有找到相关文章

最新更新