Pour tester votre code, vous devez créer une enveloppe pour les fonctions d'entrée/sortie du système. Vous pouvez le faire en utilisant l'injection de dépendances, en nous donnant une classe qui peut demander de nouveaux entiers :
public static class IntegerAsker {
private final Scanner scanner;
private final PrintStream out;
public IntegerAsker(InputStream in, PrintStream out) {
scanner = new Scanner(in);
this.out = out;
}
public int ask(String message) {
out.println(message);
return scanner.nextInt();
}
}
Ensuite, vous pouvez créer des tests pour votre fonction, en utilisant un framework mock (j'utilise Mockito) :
@Test
public void getsIntegerWhenWithinBoundsOfOneToTen() throws Exception {
IntegerAsker asker = mock(IntegerAsker.class);
when(asker.ask(anyString())).thenReturn(3);
assertEquals(getBoundIntegerFromUser(asker), 3);
}
@Test
public void asksForNewIntegerWhenOutsideBoundsOfOneToTen() throws Exception {
IntegerAsker asker = mock(IntegerAsker.class);
when(asker.ask("Give a number between 1 and 10")).thenReturn(99);
when(asker.ask("Wrong number, try again.")).thenReturn(3);
getBoundIntegerFromUser(asker);
verify(asker).ask("Wrong number, try again.");
}
Puis écrivez votre fonction qui passe les tests. La fonction est beaucoup plus propre, car vous pouvez supprimer la duplication de la demande et de l'obtention des entiers et les appels système réels sont encapsulés.
public static void main(String[] args) {
getBoundIntegerFromUser(new IntegerAsker(System.in, System.out));
}
public static int getBoundIntegerFromUser(IntegerAsker asker) {
int input = asker.ask("Give a number between 1 and 10");
while (input < 1 || input > 10)
input = asker.ask("Wrong number, try again.");
return input;
}
Cela peut sembler exagéré pour votre petit exemple, mais si vous construisez une application plus importante, un tel développement peut s'avérer rapidement payant.
7 votes
Que testez-vous, exactement ? Un scanner ? Une méthode de test doit typiquement affirmer quelque chose pour être utile.
2 votes
Vous ne devriez pas avoir à tester la classe Scanner de Java. Vous pourriez définir manuellement votre entrée et simplement tester votre propre logique. int input = -1 ou 5 ou 11 couvrira votre logique
3 votes
Six ans plus tard... et c'est toujours une bonne question. Notamment parce que lorsque vous commencez à développer une application, vous n'avez généralement pas envie d'avoir toutes les cloches et les sifflets de JavaFX, mais plutôt de commencer à utiliser l'humble ligne de commande pour un peu d'interaction très basique. Il est dommage que JUnit ne rende pas cela un peu plus facile. Pour moi, la réponse d'Omar Elshal est très bien, avec un minimum de codage d'applications "artificielles" ou "déformées"...