目前正在编写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
}
答案 0 :(得分:1)
因为这是互动的,所以很难很好地测试 - 或者至少以可读的方式测试。
测试类似代码的一种常用方法是提取一个接收Scanner和PrintWriter的方法,类似于this StackOverflow answer,并测试:
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();
// ...
}
这类似于assigning a new stdin/stdout using System.setIn
,但更具可预测性,并且需要更少的清理。但是,在这两种情况下,nextInt
等方法在等待输入时都会阻塞。除非你想让这个测试多线程(这很复杂),否则你将无法读到你的输出,直到最后,你必须预先指定所有的指令:
@Test
public void methodShouldLaunchTheSpaceShuttle() {
StringWriter output = new StringWriter();
String input = "5\n" // "Please enter another value!"
+ "10\n" // "Code accepted. Enter command:"
+ "Shuttle\n"; // "Launching space shuttle..."
systemUnderTest.method(new Scanner(input), new PrintWriter(output));
assertThat(output.toString(), contains("Please enter another value!"));
assertTrue(systemUnderTest.spaceShuttleLaunched());
}
也就是说,只要你的说明书很简单(并且没有改变),你可以添加评论(如上所述)并获得一个有价值的测试,将你的代码覆盖率提高到你需要的范围。是
(注意:当然,除了创建一个重载方法,你还可以将" scanner"和#34;输出"作为被测系统中的可变字段。我倾向于比如尽可能保持课堂无国籍,但如果对你或你的同事/导师来说这不是很大的让步。)
答案 1 :(得分:0)
您是否只提供自己的测试值?他们只是int
对吗?如果他们是原始值,你就不需要嘲笑任何东西,你可以在给定int
s的某一组时测试你的功能:
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
}
如果您依靠外部输入来使您的单元测试工作,那么这些测试并不是真正的单元测试。