Mock na HttpInputStream (odp. z internetu)

0

Hej,

Mam problem z napisaniem testow jednostkowych do mojej klasy, ktora nawiazuje polaczenie z pewnym miejscem w sieci, robi "cala magie" i dopiero zwraca wynik. Oczywiscie chcialbym testy jednostkowe odpalac bez koniecznosci polaczenia z internetem i bez uzalezniania sie czy po drugiej stronie nie padl serwer itp.

Klasa ma duzo metod prywatnych, jedna publiczna - ja wywoluje, ona po kolei wywoluje reszte i zwraca wynik. Gdybym mogl zamockowac odpowiedz z sieci to wszystko bylo by pieknie, bo reszta metod nawet by sie nie skapnela ze nie ma rzeczywistego polaczenia. Chodzi mi konkretnie o miejsce w kodzie:

  // (URLConnection connection)
  BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

czyli musialbym zamockowac wynik getInputStream(). Metoda ta zwraca mi obiekt typy HTTPInputStream, ktory jak zobaczylem w debugerze to sie przekrecilem :) Obiekt jest dosc duzy i mockowac go w calosci bedzie problem.

Macie jakies pomysly jak to rozwiazac? (ja nie jestem bardzo doswiadczonym programista wiec prosze o wyrozumialosc jezeli popisalem glupoty a rozwiazanie bedzie bardzo proste) :)

0

A nie możesz zamockować całego BufferedReadera? Ew. jeśli znasz dokładną sekwencję odwołań do tego BufferedReadera to możesz zastosować easyMock.

0

Tak, znam dokładną sekwencję wywołań - jest dość standardowa :)

StringBuilder builder = new StringBuilder()

while ((line = reader.readLine()) != null)
   builder.append(line);

return builder.toString();

Tak więc mógłbym zrzucić sobie "poprawnego" stringa i zamockować easymockiem jego zwracanie, tylko że nie wiem zbytnio jak to zrobić, bo w linijce ktora post wyzej wklejalem:

BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

w razie gdy nie jestem podlaczony do internetu

connection.getInputStream()

wyrzuca wyjatek.

Nie umiem jakos swietnie poslugiwac sie EasyMockiem, zrobilem wiec jak potrafilem:

BufferedReader mock = createMock(BufferedReader.class);
expect(mock.readLine()).andReturn("dupa");

Ale to nie dziala... Gdy nie jestem podlaczony do internetu wyjatek rzuci, gdy jestem podlaczony nie zwroci uwagi na mocka ale zwroci "prawdziwy" wynik.

Dzieki za pomoc!

0
PiotrekD napisał(a)
BufferedReader mock = createMock(BufferedReader.class);
expect(mock.readLine()).andReturn("dupa");

A replay(mock); też tam jest?
http://www.slideshare.net/subin123/easymock-tutorial

0

Tak, jest i niestety jest olewane...
Calosc wyglada tak:

Testy:

import static org.easymock.classextension.EasyMock.*;

(...)

  private MyQuery myquery;
  private BufferedReader mock;

  @Before
    public void setUp()
    {
        myquery = new MyQuery(); // ta klasa jest testowana
        // (...)
        mock = createMock(BufferedReader.class);
    }

 @Test
    public void test() throws IOException {        
        expect(mock.readLine()).andReturn("dupa");
        replay(mock);
        this.myquery.executeQuery("jakiestamzapytanie");
    }

Teraz licze ze jezeli wywolam ten test to w momencie gdy ktoras z metod w MyQuery stworzy sobie BufferedReadera, wywola na nim metode readLine() to dostanie "dupa" - nie wiem czy to dobre zalozenie :-/

Samo MyQuery:

public Result[] executeQuery(String pquery) {     
            //(...)
            String response = getResponse(connection);
            return getResults(response);       
    }

 private String getResponse(URLConnection connection) throws IOException {
        String line;
        StringBuilder builder = new StringBuilder();

        // (!!!) TUTAJ
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));        

        while ((line = reader.readLine()) != null) { // (!!!) TUTAJ            
            builder.append(line);
        }

        return builder.toString();
    }
0
PiotrekD napisał(a)

Teraz licze ze jezeli wywolam ten test to w momencie gdy ktoras z metod w MyQuery stworzy sobie BufferedReadera, wywola na nim metode readLine() to dostanie "dupa" - nie wiem czy to dobre zalozenie :-/

To jest złe założenie. Mocki tak nie działają. Przesłaniają jeden obiekt, nie całą klasę.
Musisz zmienić swoją klasę tak, aby korzystała ze stworzonego na zewnętrz bufferreadera.

0

No tak, podejrzewałem że trudno by było coś takiego zrobić jak przesłonienie całej klasy :) Dzięki!

1 użytkowników online, w tym zalogowanych: 0, gości: 1