对控制台输入法Java进行单元测试

对控制台输入法Java进行单元测试,java,unit-testing,input,console,Java,Unit Testing,Input,Console,如何能够对以下方法进行单元测试 public static String grabString() { BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); do { try { // call the readline method of the buffered reader object. return r.readLine(); } catch (Exception e)

如何能够对以下方法进行单元测试

public static String grabString() {
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
do {
  try {
    // call the readline method of the buffered reader object.
    return r.readLine();
  } catch (Exception e) {
  }
} while (true);}
如果我像这样从测试类调用这个方法

String getInput = grabString();
并用计算机进行测试

assertEquals(getInput, "hello");

是否可以使用代码在不需要键入的情况下将“hello”输入控制台,以便单元测试可以立即运行?

您可以使用
Robot
类进行此操作,方法如下:

 Robot r = new Robot();
 r.keyPress(/*Keycode for your input*/);
 r.keyRelease(/*Keycode for your input*/);
public class MyStreamReader {

    private InputStream in;

    public MyStreamReader(InputStream in) {
        this.in = in;
    }

    public String grabString() {
        BufferedReader r = new BufferedReader(new InputStreamReader(in));
        do {
            try {
                // call the readline method of the buffered reader object.
                return r.readLine();
            } catch (Exception e) {
            }
        } while (true);
    }

}
对于键盘上应按的每个键

但我怀疑这是否有意义,因为您将测试JavaAPI代码,并且应该假设这些方法可以工作


而像你这样的无限循环并不是一个好方法,无论你想实现什么

您可以使用
Robot
类来实现这一点,方式如下:

 Robot r = new Robot();
 r.keyPress(/*Keycode for your input*/);
 r.keyRelease(/*Keycode for your input*/);
public class MyStreamReader {

    private InputStream in;

    public MyStreamReader(InputStream in) {
        this.in = in;
    }

    public String grabString() {
        BufferedReader r = new BufferedReader(new InputStreamReader(in));
        do {
            try {
                // call the readline method of the buffered reader object.
                return r.readLine();
            } catch (Exception e) {
            }
        } while (true);
    }

}
对于键盘上应按的每个键

但我怀疑这是否有意义,因为您将测试JavaAPI代码,并且应该假设这些方法可以工作


而像你这样的无限循环并不是一个好方法,无论你想实现什么

我建议您不要使用静态方法,而是使用一个带有InputStream的对象(最终是singleton)作为字段。 然后,您可以在生产代码中使用real System.in,在测试中使用伪InputStream

大概是这样的:

 Robot r = new Robot();
 r.keyPress(/*Keycode for your input*/);
 r.keyRelease(/*Keycode for your input*/);
public class MyStreamReader {

    private InputStream in;

    public MyStreamReader(InputStream in) {
        this.in = in;
    }

    public String grabString() {
        BufferedReader r = new BufferedReader(new InputStreamReader(in));
        do {
            try {
                // call the readline method of the buffered reader object.
                return r.readLine();
            } catch (Exception e) {
            }
        } while (true);
    }

}
在生产代码中,您将使用System.In stream(例如
newmystreamreader(System.In)
)构造实例

在测试中,您将使用伪InputStream进行测试:

@Test
public void testGrabString() throws Exception {
    String expected = "test input from console";
    ByteArrayInputStream fakeIS = new ByteArrayInputStream(expected.getBytes());
    MyStreamReader myStreamReader = new MyStreamReader(fakeIS);

    String actual = myStreamReader.grabString();
    assertEquals(expected, actual);
}

我建议您不要使用静态方法,而是使用带有InputStream的对象(最终为singleton)作为字段。 然后,您可以在生产代码中使用real System.in,在测试中使用伪InputStream

大概是这样的:

 Robot r = new Robot();
 r.keyPress(/*Keycode for your input*/);
 r.keyRelease(/*Keycode for your input*/);
public class MyStreamReader {

    private InputStream in;

    public MyStreamReader(InputStream in) {
        this.in = in;
    }

    public String grabString() {
        BufferedReader r = new BufferedReader(new InputStreamReader(in));
        do {
            try {
                // call the readline method of the buffered reader object.
                return r.readLine();
            } catch (Exception e) {
            }
        } while (true);
    }

}
在生产代码中,您将使用System.In stream(例如
newmystreamreader(System.In)
)构造实例

在测试中,您将使用伪InputStream进行测试:

@Test
public void testGrabString() throws Exception {
    String expected = "test input from console";
    ByteArrayInputStream fakeIS = new ByteArrayInputStream(expected.getBytes());
    MyStreamReader myStreamReader = new MyStreamReader(fakeIS);

    String actual = myStreamReader.grabString();
    assertEquals(expected, actual);
}

您可以测试内置在JDK中的代码,但您可能认为它已经可以工作了。不清楚您的循环试图实现什么,也不清楚您如何触发异常。我不希望在无限循环中解决这个问题,而是用
AssetionError
来包装它,因为它不应该发生,而且您不知道如何处理它。您可以测试内置在JDK中的代码,但您可能认为它已经工作了。不清楚您的循环试图实现什么,也不清楚您如何触发异常。我不希望在无限循环中解决这个问题,而是用一个
AssetionError
来包装它,因为它不应该发生,而且您不知道如何处理它。一般来说,应该注意的是,应用程序注册击键通常需要
keyPress()
keyrease()
之间的延迟。请参阅。通常,应注意,应用程序注册击键通常需要在
keyPress()
keyrease()
之间进行延迟。看,似乎就是我要找的。谢谢,不客气。你能不能把它标记为一个答案?似乎就是我要找的。谢谢,不客气。你能把它标出来作为答案吗?