2010-09-28 14 views
8

w naszej aplikacji, oczekujemy, wprowadzanych przez użytkownika w obrębie Thread następująco:Zapisywanie danych na System.in

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

Chcę przekazać tę część w moim badanej jednostki tak, że mogę wznowić wątek, aby wykonać reszta kodu. Jak mogę napisać coś do System.in z junit?

+1

Nie sądziłem, że pan może, ale podobno można zgodnie z Justinem. Czy nie lepiej jednak zrestrukturyzować testowany kod, aby wprowadzić strumień wejściowy z zewnątrz? –

+0

@Bart, jeśli testujesz aplikację, która pobiera dane wejściowe z 'System.in', w końcu będziesz chciał przetestować moduł, który pobiera dane z' System.in'. – jjnguy

+2

@Justin Czy to nie jest testowanie Java, a nie twój kod? Jeśli wprowadzisz InputStream, nadal testujesz cały kod i w zależności od języka Java, aby zapewnić poprawne System.in. –

Odpowiedz

20

Co chcesz zrobić, to użyć metody setIn() z System. Umożliwi to przekazanie danych do System.in z junit.

+0

To działa, gdy uruchamiam testy JUnit indywidualnie, ale kiedy uruchamiam całą klasę mój program wydaje się przeciągać w punktach, w których powinna działać funkcja setIn(). Czy ktokolwiek inny ma ten problem, a jeśli tak, wszelkie pomysły na jego obejście? – decal

+0

@dekologicznie problem mógł być niepoprawny setup() i tearDown() modyfikujący te wartości System.in() i System.out(). Istnieją inne odniesienia do tego problemu w innych miejscach SE. Jeśli ktokolwiek zobaczy ten komentarz, przeszukuję i zamienię .. – Crowie

9

Wymień go na czas trwania testu:

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

Mały detal: ponieważ buforowany czytnik jest skonstruowany bez zestawu znaków, nie powinieneś wywoływać 'getBytes()' również bez zestawu znaków (lub, oczywiście, dodać charset do bufferedreader)? –

5

Zamiast sugestii powyżej (edit: Zauważyłem, że Bart opuścił ten pomysł w komentarzu również), i sugeruje dokonywania klasę więcej jednostek można przetestować, nadając klasie akceptację źródła wejściowego jako parametr konstruktora lub podobny (wstrzyknij zależności). Klasa i tak nie powinna być tak połączona z System.in.

Jeśli klasa jest wykonana z Reader, można po prostu to zrobić:

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")); 
Powiązane problemy