0

下面是一个java程序来猜测汤姆有多少个苹果。如果汤姆的苹果数量比猜测的数量多,汤姆就会打得更高,如果它更少,他就会打低。当猜到的数字正确时,他会回答没有。我的任务是为这个程序编写一个 JUnit 测试用例。由于基于用户输入,猜测的数字要么递减要么递增,直到我们达到实际值,这让我对如何为该程序编写 JUnit 测试用例感到困惑

  public static void main(String args[]){
      System.out.println("Guess the number of Apples Tom has");
      Scanner sc= new Scanner(System.in);
      int number=sc.nextInt();
      System.out.println("Tom, is it higher or lower?");
      String higherOrLower=sc.nextLine();

      while(true){
          number= getValue(higherOrLower,number);
          System.out.println("Tom, is it higher or lower?");
          higherOrLower=sc.nextLine();
          if(higherOrLower.equalsIgnoreCase("none")) {
                break;
          }
      }
  }

  public static int getValue(String i,int j){

        if(i.equalsIgnoreCase("lower")) {
            j--;
            return j;
        } else if(i.equalsIgnoreCase("higher")) {
            j++;
            return j;
        } else {
            return j;
        }
    }
4

1 回答 1

0

好的,让我们在这里详细介绍一下...

好的单元测试的基础是好的代码。这就解释了为什么编写单元测试不仅使代码工作更可靠,而且还倾向于使编码人员编写更好的代码(因为糟糕的代码通常很难测试)。

在您的示例中,您有两种方法(我假设您还没有深入了解面向对象编程(OOP)的细节,所以我不会讨论如何使用其他类更好地构造您的代码)。

一种方法进行实际的数字运算(好吧,一点点运算),另一种方法进行输入。不幸的是,您的输入法也是您的主要方法,因此您可以做得更好一些,因为主要方法不太适合测试。

public static void main(String[] args) {

    Scanner scanner = new Scanner(System.in); // We'll ignore finer problems with scanners, etc. here
    playGame(scanner);

}

public static void playGame(Scanner scanner) {
    System.out.println("Guess the number of Apples Tom has");
    Scanner sc= new Scanner(System.in);
    int number=sc.nextInt();
    System.out.println("Tom, is it higher or lower?");
    String higherOrLower=sc.nextLine();

    while(true){
        number= getValue(higherOrLower,number);
        System.out.println("Tom, is it higher or lower?");
        higherOrLower=sc.nextLine();
        if(higherOrLower.equalsIgnoreCase("none")) {
            break;
        }
    }
}

这个小改动将使您的代码更易于测试。让我们从简单的部分开始,getValue方法:@Test public void lower_should_return_number_minus_1() { int result = getValue("lower", 10); 断言.assertEquals(9, 结果); // 简单的断言 }

@Test
public void higher_should_return_number_plus_1() {
    int result = getValue("higher", 10);
    Assert.assertEquals(11, result); // simple assertions
}

@Test
public void garbage_should_return_same_number() {
    int result = getValue("Hello, Polly!", 10);
    Assert.assertEquals(10, result); // simple assertions
}

这将测试您的大部分可能性。如果您为字符串输入 null,最好也测试一下会发生什么,以确保 ;-)

测试另一种方法会有点困难,因为它涉及一些技巧......

@Test(timeout=1000)
public void game_should_work_on_input() {
    final ByteArrayInputStream stream = new ByteArrayInputStream(String.format("5%nlower%nlower%nnone%n").getBytes());
    final Scanner scanner = new Scanner(stream);
    playGame(scanner);
}

这里我们简单地创建一个“假”输入,它由“5”、“lower”、“lower”和“none”组成(老实说,在 5 和第一个 lower 之间有一个空行)。String.format将为每个添加正确的新行字符%n。如果您的测试成功,则意味着游戏已经玩到了最后。如果没有,超时将在 1000 毫秒后发生(这意味着您的游戏没有正确结束,它应该正确结束)。老实说,没有测试它,但你可以从那里开始,我敢肯定。;-)

于 2016-02-23T08:59:38.833 回答