Java Input/Output Tests Junit?

jo135  22.10.2023, 17:12

Ist das zu testende Programm in dieser Form fix vorgegeben, oder kannst du was dran ändern? Das wäre für Testbarkeit sinnvoll.

frage416 
Fragesteller
 22.10.2023, 17:29

Leider nur sehr begrenzt. Die Methoden müssen alle privat sein. Was wäre denn dein Vorschlag gewesen?

1 Antwort

Ganz allgemein: ein vernünftig testbares Programm hat eben keine hartkodierten Abhängigkeiten auf bestimmte Ressourcen wie solche Streams. Der Trick mit dem Umhängen von System.in ist halt eher ein...fauler Trick mit diversen Nachteilen (z.B. gilt es prozessweit, was bei parallelen Tests zu sehr unschönen Effekten führt).

Sinnvollerweise könnte man also der UserInteraction direkt jene Streams übergeben, die zu verwenden sind, Default ist halt weiterhin System.in/System.out. Man könnte auch noch weiter gehen und die Ein- und Ausgabe durch Strings ersetzen, die dann injiziert bzw. abgefangen werden.

Aber wenn das nicht geht:

        String input = "1\nJohn\n";

Hier hast du hartkodierte Zeilenenden nach Unix-Manier. Auf Windows ist aber \r\n nötig. Auf welchem OS testest du? Mit printf() kannst du %n verwenden, oder du kannst den jeweiligen Line Separator mit https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/System.html#lineSeparator() holen.

Mir ist auch unklar, warum du hier Program instanziierst, statt UserInteraction. Offenbar ist die doch die eigentliche Main-Klasse, die dann ihrerseits Program instanziiert?

        program = new Program();
        try {
            program.main(null);

Dann noch ein Thema:

    private String readInput() {
        return (new Scanner(System.in)).nextLine();
    }

Hier wird für jede einzelne Eingabe sinnlos ein neues Scanner-Objekt erzeugt. Wozu?

Und dann solltest du noch bedenken, dass dein Programm auch stderr für Ausgaben verwendet (für Fehlermeldungen).

Das sind die Dinge, die aufs erste Drüberlesen auffallen.