Java, Junit-capturer l'entrée / sortie standard pour une utilisation dans un test de l'unité [dupliquer]
cette question a déjà une réponse ici:
- JUnit test pour le Système.hors.println () 12 réponses
J'écris des tests d'intégration en utilisant JUnit pour automatiser les tests d'une application basée sur console. L'application est un devoir, mais cette partie n'est pas un devoir. Je veux automatisez ces tests pour être plus productif -- Je ne veux pas avoir à revenir en arrière et à tester à nouveau des parties déjà testées de l'application. (Standard raisons d'utiliser les tests Unitaires)
de toute façon, je ne peux pas comprendre ou trouver un article sur la capture de la sortie pour que je puisse faire assertEquals
sur elle ni fournir l'entrée automatisée. Je ne me soucie pas si la sortie/entrée va à la console/panneau de sortie. J'ai seulement besoin de faire exécuter le test et de vérifier que la sortie est ce qui est attendu compte tenu de l'entrée.
N'importe qui a un article ou un code pour aider avec ceci.
3 réponses
Utiliser Du Système.setOut () (et System.setErr()
) pour rediriger la sortie vers un printstream arbitraire - qui peut être celui que vous lisez depuis un programme.
par exemple:
final ByteArrayOutputStream myOut = new ByteArrayOutputStream();
System.setOut(new PrintStream(myOut));
// test stuff here...
final String standardOutput = myOut.toString();
la classe System
a des méthodes setIn()
, setOut()
et setErr()
qui vous permettent de définir les flux d'entrée, de sortie et d'erreur standard, par exemple à un ByteArrayOutputStream
que vous pouvez inspecter à volonté.
Voici la solution à la place de ByteArrayOutputStream. Il n'ajoute rien à l'idée de Système.énoncées. Plutôt, je veux partager la mise en œuvre qui est mieux que de tout capturer dans ByteArrayOutputStream. Je préfère ne capturer que les informations sélectionnées et laisser apparaître tous les messages log dans la console au fur et à mesure qu'ils sont journalisés plutôt que de tout capturer dans une balckbox (de quelle taille?) pour traitement ultérieur.
/**
* Once started, std output is redirected to this thread.
* Thread redirects all data to the former system.out and
* captures some strings.*/
static abstract class OutputCaputre extends Thread {
// overrdie these methods for System.err
PrintStream getDownstream() { return System.out;}
void restoreDownstream() { System.setOut(downstream);}
// will be called for every line in the log
protected abstract void userFilter(String line);
final PrintStream downstream;
public final PipedInputStream pis;
private final PipedOutputStream pos;
OutputCaputre() throws IOException {
downstream = getDownstream();
pos = new PipedOutputStream();
pis = new PipedInputStream(pos);
System.setOut(new PrintStream(pos));
start();
}
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(pis));
// once output is resotred, we must terminate
while (true) {
String line = br.readLine();
if (line == null) {
return;
}
downstream.println(line);
userFilter(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void terminate() throws InterruptedException, IOException {
restoreDownstream(); // switch back to std
pos.close(); // there will be no more data - signal that
join(); // and wait until capture completes
}
};
voici un exemple d'utilisation de la classe:
OutputCaputre outputCapture = new OutputCaputre() {
protected void userFilter(String line) {
downstream.println("Capture: " + line);
}
};
System.out.println("do you see me captured?");
// here is your test
outputCapture.terminate(); // finally, stop capturing