eclipse junit system.in java

时间:2015-10-04 11:55:17

标签: java junit system.in

我正在尝试在使用scanner和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类传递给正在测试的类。

帮助?

2 个答案:

答案 0 :(得分:1)

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

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));
  }

}

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

因此,如果您没有看到正确的行为,则测试可能会被破坏或问题出现在您的代码的另一个区域,而您尚未发布。那么问问你自己:你的例子与这个例子有什么不同?

答案 1 :(得分:0)

单元测试期间,你应弄乱System.in

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

你的代码可能做了三件事:

  • 询问用户输入
  • 执行操作
  • 显示结果

单元测试中,您正在测试操作,而不是用户提示或显示逻辑。或者,如果你这样做,它们应该是3个不同的单元测试,并记住,如果你正在测试用户提示,你正在测试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创建新类。它们也可以是同一类,例如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);
}