我正在尝试在使用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类传递给正在测试的类。
帮助?
答案 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
}
如果它们是简单值,则不必为Input
和Result
创建新类。它们也可以是同一类,例如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);
}