带有假用户输入的Java测试扫描仪

带有假用户输入的Java测试扫描仪,java,unit-testing,junit,mockito,console-application,Java,Unit Testing,Junit,Mockito,Console Application,我有一个静态方法,它使用静态最终扫描仪从控制台获取用户输入 当进行测试时,我想创建一些具有不同输入的测试(显然)。只要测试是单独运行的,这就可以正常工作。运行整个类不起作用,因为(显然)扫描器已经用来自上一个测试的输入初始化,该测试没有比第一个测试所需的更多的行 我得到的具体错误是: java.util.NoSuchElementException: No line found 以下是一些澄清代码: public class UserInputHandler { public stat

我有一个
静态
方法,它使用
静态最终
扫描仪
从控制台获取用户输入

当进行测试时,我想创建一些具有不同输入的测试(显然)。只要测试是单独运行的,这就可以正常工作。运行整个类不起作用,因为(显然)扫描器已经用来自上一个测试的输入初始化,该测试没有比第一个测试所需的更多的行

我得到的具体错误是:

java.util.NoSuchElementException: No line found
以下是一些澄清代码:

public class UserInputHandler {
    public static final Scanner SCANNER = new Scanner(System.in);
}
我试图测试的类(以及其他一些类)正在使用上面的
Scanner
查询用户

我的测试:

InputStream in = new ByteArrayInputStream("test".getBytes());
System.setIn(in);
TestClass testclass = new TestClass();
testClass.method(); // Scanner is used in this method

如何让我的测试为多个TestClass实例工作?

真正的问题在于:

public class UserInputHandler {
    public static final Scanner SCANNER = new Scanner(System.in);
}
您正在强制该输入来自
系统中的
。为什么不使用

public class UserInputHandler {
    public Scanner getScanner() {
      return new Scanner(someInputStream);
当然,现在您必须担心
someInputStream
来自何方,但是:您使自己变得更加灵活

您的代码实际上并不在单个静态对象上,而是进行调用并接收从某处读取的内容。然后,在测试中,您只需定义输入流,并确保可以使用这些输入流(例如,通过将其设置为UserInputHandler类的字段,在实例化该类时设置该字段)

换句话说:真正的解决方案是更改生产代码,使其A)更加灵活,B)易于测试。您的做法是倒退的:您编写了不灵活且难以测试的代码,现在您试图使您的测试用例变得合理


错误的方法:当您不能编写简单、直接的测试时,您的生产代码需要重新编写。始终如此。

真正的问题在于:

public class UserInputHandler {
    public static final Scanner SCANNER = new Scanner(System.in);
}
您正在强制该输入来自
系统中的
。为什么不使用

public class UserInputHandler {
    public Scanner getScanner() {
      return new Scanner(someInputStream);
当然,现在您必须担心
someInputStream
来自何方,但是:您使自己变得更加灵活

您的代码实际上并不在单个静态对象上,而是进行调用并接收从某处读取的内容。然后,在测试中,您只需定义输入流,并确保可以使用这些输入流(例如,通过将其设置为UserInputHandler类的字段,在实例化该类时设置该字段)

换句话说:真正的解决方案是更改生产代码,使其A)更加灵活,B)易于测试。您的做法是倒退的:您编写了不灵活且难以测试的代码,现在您试图使您的测试用例变得合理


错误的方法:当您不能编写简单、直接的测试时,您的生产代码需要重新编写。总是这样。

谢谢你的回答,到时候我必须再考虑一下设计。你是否也考虑添加一个构造函数注入的示例?我可以这样做。希望我能记得在本周晚些时候做这件事。谢谢你的回答,到时候我必须再考虑一下设计。你会考虑为构造函数注入添加一个例子吗?我可以做到。希望我能记得在本周晚些时候这样做。