El problema con BufferedReader.readLine()
es que se trata de un método de bloqueo que espera la entrada del usuario.Me parece que no desea particularmente simular eso (es decir, desea que las pruebas sean rápidas). Pero en un contexto de prueba continuamente devuelve null
a alta velocidad durante la prueba, lo cual es molesto.
Para un purista puedes hacer el getInputLine
debajo del paquete privado, y burlarlo: fácil de pelar.
String getInputLine() throws Exception {
return br.readLine();
}
... tendría que asegurarse de que tenía una forma de detener (normalmente) un bucle de interacción del usuario con la aplicación. También tendría que lidiar con el hecho de que sus "líneas de entrada" siempre serían las mismas hasta que de alguna manera haya cambiado el doReturn
de su simulacro: apenas típico de la entrada del usuario.
para un no-purista que quiere hacer la vida más fácil para ellos mismos (y producir pruebas legibles) se puede poner todo esto más adelante en su código de aplicación:
private Deque<String> inputLinesDeque;
void setInputLines(List<String> inputLines) {
inputLinesDeque = new ArrayDeque<String>(inputLines);
}
private String getInputLine() throws Exception {
if (inputLinesDeque == null) {
// ... i.e. normal case, during app run: this is then a blocking method
return br.readLine();
}
String nextLine = null;
try {
nextLine = inputLinesDeque.pop();
} catch (NoSuchElementException e) {
// when the Deque runs dry the line returned is a "poison pill",
// signalling to the caller method that the input is finished
return "q";
}
return nextLine;
}
... en su prueba que podría luego ir así:
consoleHandler.setInputLines(Arrays.asList(new String[]{ "first input line", "second input line" }));
antes de desencadenar el método en esta clase "ConsoleHandler" que necesita líneas de entrada.
Desde una perspectiva de TDD, esto evita el diseño que la prueba es "conducción" o tratar de indicar. Sin embargo, el OP no especificó TDD, y desde una perspectiva de prueba posterior, es algo muy razonable de hacer: aprovechar el sistema global. – Yishai
No puede simplemente hacer System.in = xxx como System.in es final. Puedes usar System.setIn, pero asegúrate de volver al valor predeterminado en el desglose. Además, no necesita pasar su propio InputStream, ByteArrayInputStream hará el trabajo muy bien. –
Oohh yeap, me confundí. Lo que intenté decir fue ... bueno, editaré mi entrada :) – OscarRyz