1

How is it possible to unit test the following method?

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);}

If I call this method from the test class like so

String getInput = grabString();

And test it with

assertEquals(getInput, "hello");

Is it possible to use code to enter "hello" into the console without the need of typing so that the unit test can run instantly?

nut0ner
  • 13
  • 4
  • 1
    You could test the code which is built into the JDK, but you might assume it works already. It's unclear what your loop is trying to achieve nor how you trigger such as Exception. Instead of hoping that in infinite loop solves the problem, I would wrap it with an `AssetionError` because it shouldn't happen and you don't know how to handle it. – Peter Lawrey Jan 03 '16 at 14:25

2 Answers2

0

You could use the Robot class for that in a manner like this:

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

for every single key that should be pressed on the keyboard.

But I doubt that makes sense as you would be testing Java API code and you should assume that these methods work!

And an infinite loop like yours is not a nice way whatever you are trying to achieve!

Java Doe
  • 346
  • 2
  • 6
  • In general, it should be noted that a delay is usually required between `keyPress()` and `keyRelease()` for an application to register the keystroke. See [here](http://stackoverflow.com/questions/25909039/java-awt-robot-inside-games/25909490#25909490). – bcsb1001 Jan 03 '16 at 14:33
0

I advise you no to use static method, but rather have an object (eventually singleton) with an InputStream as a field. Then you can use real System.in in your production code and fake InputStream in the test.

Something like this:

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);
    }

}

In production code, you'll construct the instance with System.in stream (e.g. new MyStreamReader(System.in)).

In tests, you'll test using fake 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);
}
David Siro
  • 1,826
  • 14
  • 33