Je cherche un moyen de vérifier avec Mockito, qu'il n'y a pas eu d'interaction avec une maquette donnée lors d'un test. C'est facile à réaliser pour une méthode donnée avec le mode de vérification never()
, mais je n'ai pas encore trouvé de solution pour la maquette complète.
Ce que je veux réellement réaliser: vérifier dans les tests, que rien n'est imprimé sur la console. L'idée générale avec jUnit va comme ça:
private PrintStream systemOut;
@Before
public void setUp() {
// spy on System.out
systemOut = spy(System.out);
}
@After
public void tearDown() {
verify(systemOut, never()); // <-- that doesn't work, just shows the intention
}
Un PrintStream
a des tonnes de méthodes et je ne veux vraiment pas vérifier chacune avec une vérification distincte - et la même chose pour System.err
...
J'espère donc, s'il existe une solution simple, que je peux, étant donné que j'ai une bonne couverture de test, forcer les ingénieurs logiciels (et moi-même) à supprimer leur (mon) code de débogage comme System.out.println("Breakpoint#1");
ou e.printStacktrace();
avant de valider les modifications.
Utilisez ceci :
import static org.mockito.Mockito.verifyZeroInteractions;
// ...
private PrintStream backup = System.out;
@Before
public void setUp() {
System.setOut(mock(PrintStream.class));
}
@After
public void tearDown() {
verifyZeroInteractions(System.out);
System.setOut(backup);
}
verifyZeroInteractions(systemOut);
Comme indiqué dans les commentaires, cela ne fonctionne pas avec un espion.
Pour une réponse à peu près équivalente mais plus complète, voir la réponse de gontard à cette question.
Vous pouvez essayer une approche légèrement différente:
private PrintStream stdout;
@Before public void before() {
stdout = System.out;
OutputStream out = new OutputStream() {
@Override public void write(int arg0) throws IOException {
throw new RuntimeException("Not allowed");
}
};
System.setOut(new PrintStream(out));
}
@After public void after() {
System.setOut(stdout);
}
Si vous préférez, vous pouvez changer le type anonyme pour une maquette et vérifier comme le suggère Don Roby .
Une façon de résoudre ce problème consiste à refactoriser la classe que vous testez, pour permettre l'injection d'un PrintStream qui peut être utilisé pour la sortie. Cela vous permettra de le tester à l'unité, sans vous fier au comportement de la classe System
. Vous pouvez utiliser un constructeur package-private pour cette injection, car vous ne l'utiliserez que depuis la classe de test correspondante. Cela pourrait donc ressembler à ceci.
public class MyClass{
private PrintWriter systemOut;
public MyClass(){
this(System.out);
}
MyClass(PrintWriter systemOut){
this.systemOut = systemOut;
// ...any other initialisation processing that you need to do
}
}
et dans la classe elle-même, utilisez la variable systemOut au lieu de System.out partout où vous appelez cette dernière.
Maintenant, dans la classe de test, créez un mock PrintStream
, et passez-le au constructeur package-private, pour obtenir l'objet que vous allez tester. Vous pouvez maintenant exécuter toutes les actions que vous souhaitez à partir de vos tests et utiliser verify
pour vérifier leurs effets sur votre maquette PrintStream
.