2010-09-28 18 views
8

In unserer Anwendung erwarten wir, dass Benutzereingaben innerhalb eines Thread wie folgt:Schreiben von Daten auf System.in

BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 

Ich möchte, dass ein Teil in meiner Einheit Test bestehen, so dass ich den Faden wieder aufnehmen kann, die zur Ausführung Rest des Codes. Wie kann ich etwas in System.in von Junit schreiben?

+1

Ich glaube nicht, Sie könnten, aber anscheinend kann man Justin nach. Wäre es jedoch nicht besser, den getesteten Code umzuformatieren, um den Eingangsstrom von außen einzufügen? –

+0

@Bart, wenn Sie eine App testen, die Eingaben von 'System.in' nimmt, möchten Sie eventuell das Modul testen, das die Daten von' System.in' übernimmt. – jjnguy

+2

@Justin Testen Sie Java nicht und nicht Ihren Code? Wenn Sie den InputStream injiziert haben, testen Sie immer noch Ihren gesamten Code und abhängig von Java, um eine korrekte System.in bereitzustellen. –

Antwort

20

Was möchten Sie tun, verwenden Sie die Methode setIn() von System. Dadurch können Sie Daten von Junit an System.in übergeben.

+0

Das funktioniert, wenn ich die JUnit-Tests einzeln ausführe, aber wenn ich die gesamte Klasse laufe, scheint mein Programm an den Stellen zu stehen, an denen setIn() funktionieren sollte. Hat jemand anderes dieses Problem, und wenn ja, irgendwelche Ideen, wie man es umgehen kann? – decal

+0

@decal Sie haben möglicherweise ein falsches setup() & tearDown() Problem gefunden, das diese Werte System.in() und System.out() geändert hat. Es gibt einige andere Verweise auf dieses Problem an anderer Stelle auf SE. Wenn jemand anderes diesen Kommentar sieht, suche und ersetze ich ihn. – Crowie

9

Ersetzen Sie ihn für die Dauer des Tests:

String data = "the text you want to send"; 
InputStream testInput = new ByteArrayInputStream(data.getBytes("UTF-8")); 
InputStream old = System.in; 
try { 
    System.setIn(testInput); 

    ... 
} finally { 
    System.setIn(old); 
} 
+0

Kleines Detail: da der bufferedreader ohne einen Zeichensatz aufgebaut ist, solltest du 'getBytes()' auch nicht ohne Zeichensatz aufrufen (oder natürlich einen Zeichen zum gepufferten Leser)? –

5

Anstelle der oben genannten Vorschläge (bearbeiten: Ich habe bemerkt, dass Bart diese Idee in einem Kommentar als auch links), würde ich Ihre Klasse schlagen vor, mehr Einheiten testbar, indem die Klasse die Eingabequelle als Konstruktorparameter oder ähnliches akzeptiert (die Abhängigkeit injizieren). Eine Klasse sollte ohnehin nicht mit System.in gekoppelt sein.

Wenn Ihre Klasse aus einem Reader aufgebaut ist, können Sie dies nur tun:

class SomeUnit { 
    private final BufferedReader br; 
    public SomeUnit(Reader r) { 
     br = new BufferedReader(r); 
    } 
    //... 
} 

//in your real code: 
SomeUnit unit = new SomeUnit(new InputStreamReader(System.in)); 

//in your JUnit test (e.g.): 
SomeUnit unit = new SomeUnit(new StringReader("here's the input\nline 2")); 
Verwandte Themen