首先,我试图在这个很酷的网站上寻找一些解决方案。我发现了一个与我的问题有关的问题,但我的测试仍然失败。 我找到的问题可以在这里找到:JUnit testing with simulated user input
让我们看看我的实施:
我有一个用户交互服务类,读取然后验证用户输入:UserInteractionService.java
package Services;
import java.util.Scanner;
public class UserInteractionService {
private static Scanner scanner = new Scanner(System.in);
public static int readIntegerAndValidate() {
while (!scanner.hasNextInt()) {
System.out.println("It is not a valid integer number. Try again!");
scanner.next();
}
return scanner.nextInt();
}
public static double readDoubleAndValidate() {
while (!scanner.hasNextDouble()) {
System.out.println("It is not a valid number. Try again!");
scanner.next();
}
return scanner.nextDouble();
}
}
当然,我有一个这个服务类的测试类:UserInteractionServiceTest.java
@Test
public void userWriteInput_checkIfItIsInteger_userTypedInteger() {
String inputData = "5";
System.setIn(new ByteArrayInputStream(inputData.getBytes()));
int input = readIntegerAndValidate();
assertEquals(5, input);
}
@Test
public void userWriteDouble_checkIfItIsDouble_userTypedDouble() {
String inputData = "5.3";
System.setIn(new ByteArrayInputStream(inputData.getBytes()));
double input = readDoubleAndValidate();
assertEquals(5.3, input, 0);
}
好吧,我的第二个测试函数(userWriteDouble_checkIfItIsDouble_userTypedDouble)失败了,我找不到原因......正如你所看到的,我使用了与de first test相同的模式。你有什么看法,为什么这个测试失败了?我应该使用一些模拟框架(Mockito)吗?提前感谢您的答案!
失败追踪:
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at Services.UserInteractionService.readDoubleAndValidate(UserInteractionService.java:21)
at Services.UserInteractionServiceTest.userWriteDouble_checkIfItIsDouble_userTypedDouble(UserInteractionServiceTest.java:23)
...
答案 0 :(得分:2)
通过使扫描程序保持静态,您更难以测试代码。我会考虑给UserInteractionService一个带有Scanner的构造函数。我建议使用EasyMock,测试中的代码看起来像
import static org.easymock.EasyMock.*;
Scanner scanner = createMock(Scanner.class);
expect(scanner.hasNextDouble()).and return(true).once();
expect(scanner.nextDouble()).and return(5.3).once();
replay(scanner);
您在测试中调用的服务将是
new UserInteractionService (scanner)
答案 1 :(得分:1)
不要为Scanner
使用静态字段。它在第一次创建时存储对System.in
的引用。在第二次测试中将System.in
再次设置为其他值不会更改Scanner
的{{1}}。像这样修改你的类代码可以修复你的测试。
System.in
顺便说一句,你应该在测试后恢复private Scanner scanner = new Scanner(System.in);
。我编写了一个名为System Rules的库,可以更轻松地为从System.in
读取的代码编写测试。