日食 junit system.in java

eclipse junit system.in java

我正在尝试使用扫描仪和 System.in.

对调用用户输入的方法创建一个 junit 测试

正在测试的方法如下所示:

public void setUserAnswer(){
    Scanner input = new Scanner(System.in);
    userAnswer = input.nextInt();
}

目前,我在 jUnit 中使用以下设置:

StringBuilder sb = new StringBuilder();
        sb.append("");
        sb.append((problem.getOperand1()+problem.getOperand2()));
        String data = sb.toString();
        System.setIn(new ByteArrayInputStream(data.getBytes()));

operand1 和 operand2 是用户添加并输入答案的随机生成的数字。

我遇到的问题是 System.setIn 没有从 jUnit class 传递到正在测试的 class。

帮忙?

为了减少讨论,您的方法可以通过以下方式进行测试:

public class MathProblem {

  private int userAnswer;

  public void setUserAnswer(){
    Scanner input = new Scanner(System.in);
    userAnswer = input.nextInt();
  }

  public int getUserAnswer() {
    return userAnswer;
  }
}

现在是测试:

public class MathProblemTest {

  private MathProblem mathProblem;

  @Before
  public void before() throws Exception {
    mathProblem = new MathProblem();
  }

  @Test
  public void testGetUserAnswer() throws Exception {
    StringBuilder sb = new StringBuilder();
    sb.append("41 20");
    String data = sb.toString();
    System.setIn(new ByteArrayInputStream(data.getBytes()));

    mathProblem.setUserAnswer();

    assertThat(mathProblem.getUserAnswer(), equalTo(41));
  }

}

正如其他人已经提到的那样:此代码的行为符合预期。

因此,如果您没有看到正确的行为,则测试可能已中断,或者问题出在代码的另一个区域,您尚未发布。所以问问你自己:你的例子与这个例子有什么不同?

unit 测试期间,您应该 搞乱 System.in

问问自己,您正在测试的是什么。您是在测试 Scanner 代码,还是使用用户输入的任何值的代码?

您的代码可能做了 3 件事:

  • 要求用户输入
  • 执行操作
  • 显示结果

unit 测试中,您测试的是操作,而不是用户提示或显示逻辑。或者如果你这样做,它们应该是 3 个不同的单元测试,请记住,如果你正在测试用户提示,你正在测试 Scanneruse,而不是Scanner 是否可以读取 System.in.

因此,首先将您的代码拆分为:

public class MyClass {
    public static void main(String[] args) {
        Input input = promptUserForInput(new Scanner(System.in), System.out);
        Result result = performOperation(input);
        printResult(System.out, result);
    }
    // methods here
}

您不必为 InputResult 创建新的 classes,如果它们是简单值。它们也可以是相同的 class,例如MyClass.

的实例

通过这种方式,您可以测试该操作是否适用于各种输入,这是您最关心的问题。

@Test
public void testOperation1() {
    Input input = new Input(5, 15, true); // true means subtract
    Result result = MyClass.performOperation(input);
    assertEquals(-10, result.getValue());
}

@Test
public void testOperation2() {
    Input input = new Input(5, 15, false); // false means add
    Result result = MyClass.performOperation(input);
    assertEquals(20, result.getValue());
}

如果需要,您还可以测试用户提示和结果打印。

@Test
public void testPrompt() {
    String userInput = "5 15\nYes";
    PrintStream out = new PrintStream(new ByteArrayOutputStream());
    Input input = MyClass.promptUserForInput(new Scanner(userInput), out);
    assertEquals(5, input.getNum1());
    assertEquals(15, input.getNum2());
    assertTrue(input.isSubtractRequested());
}

@Test
public void testPrint() {
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    try (PrintStream out = new PrintStream(buf)) {
        MyClass.printResult(out, new Result(-10));
    }
    String outText = new String(buf.toByteArray());
    assertEquals("Result is -10\r\n", outText);
}