93 votes

Test JUnit avec entrée utilisateur simulée

J'essaie de créer des tests JUnit pour une méthode qui nécessite une entrée utilisateur. La méthode testée ressemble un peu à la méthode suivante :

public static int testUserInput() {
    Scanner keyboard = new Scanner(System.in);
    System.out.println("Give a number between 1 and 10");
    int input = keyboard.nextInt();

    while (input < 1 || input > 10) {
        System.out.println("Wrong number, try again.");
        input = keyboard.nextInt();
    }

    return input;
}

Existe-t-il un moyen de passer automatiquement un int au programme au lieu que moi ou quelqu'un d'autre le fasse manuellement dans la méthode de test JUnit ? Comme simuler l'entrée de l'utilisateur ?

Merci d'avance.

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"...

3voto

J'ai résolu le problème de la lecture depuis stdin pour simuler une console...

Mon problème est que je voudrais essayer d'écrire dans un test JUnit la console pour créer un certain objet...

Le problème est comme vous le dites : Comment puis-je écrire dans le Stdin du test JUnit ?

Ensuite, à l'université, j'ai appris les redirections comme vous dites System.setIn(InputStream) change le descripteur de fichier stdin et vous pouvez écrire dedans alors....

Mais il y a un autre problème à résoudre... le bloc de test JUnit attend la lecture de votre nouvel InputStream, donc vous devez créer un thread pour lire depuis l'InputStream et depuis le Thread de test JUnit écrire dans le nouveau Stdin... D'abord vous devez écrire dans le Stdin parce que si vous écrivez plus tard de créer le Thread pour lire de stdin vous aurez probablement des conditions de course... vous pouvez écrire dans l'InputStream avant de lire ou vous pouvez lire de l'InputStream avant d'écrire...

Voici mon code, mon anglais est mauvais, j'espère que vous pouvez tous comprendre le problème et la solution pour simuler l'écriture dans stdin à partir du test JUnit.

private void readFromConsole(String data) throws InterruptedException {
    System.setIn(new ByteArrayInputStream(data.getBytes()));

    Thread rC = new Thread() {
        @Override
        public void run() {
            study = new Study();
            study.read(System.in);
        }
    };
    rC.start();
    rC.join();      
}

1voto

massfords Points 612

J'ai trouvé utile de créer une interface qui définit des méthodes similaires à java.io.Console et de l'utiliser pour lire ou écrire dans System.out. L'implémentation réelle déléguera à System.console() tandis que votre version JUnit peut être un objet fantaisie avec des entrées prédéfinies et des réponses attendues.

Par exemple, vous construiriez un MockConsole qui contiendrait l'entrée en conserve de l'utilisateur. L'implémentation fantaisie extrait une chaîne d'entrée de la liste à chaque fois que readLine est appelé. Elle recueille également toutes les sorties écrites dans une liste de réponses. À la fin du test, si tout s'est bien passé, toutes les entrées auront été lues et vous pourrez faire une assertion sur la sortie.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X