2013-12-13 15 views
6

mam zgaszone JSON obiektu, ale trzeba mock po użyciu Mockito:Korzystanie Mockito dla klienta HTTP

HttpResponse response = defaultHttpClient.execute(postRequest); 
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 
StringBuilder result = new StringBuilder(); 
while ((line = rd.readLine()) != null) { 
    result.append(line);   
} 
JSONObject jsonResponseObject = new JSONObject(result.toString()); 

stworzyłem następujące Mocks:

@Mock 
    private HttpClient mockHttpClient; 
    private HttpPost mockHttpPost; 
    private HttpResponse mockHttpResponse; 
    private HttpEntity mockHttpEntity; 
    private InputStream mockInputStream; 
    private InputStreamReader mockInputStreamReader; 
    private BufferedReader mockBufferedReader; 

i mają następujące when sprawozdań :

Mockito.when(mockHttpClient.execute(mockHttpPost)).thenReturn(mockHttpResponse); 
    Mockito.when(mockHttpResponse.getEntity()).thenReturn(mockHttpEntity); 
    Mockito.when(mockHttpEntity.getContent()).thenReturn(mockInputStream); 

Pytanie: Czy muszę utworzyć wszystkie te statuty "kiedy" ents, a jeśli tak, to jakie inne muszę utworzyć, aby móc dostać się do zgaszonego JSON?

Jakieś sugestie, proszę, pls?

Dzięki

+0

Dodaj więcej kodu, abyśmy mogli dokładnie zrozumieć kpiny z obiektów. –

+0

Czy używasz jakichkolwiek frameworków internetowych, takich jak Spring MVC? – SergeyB

Odpowiedz

1

Tak, może być konieczne, gdy wszystkie oświadczenia, że ​​już wspomniano. Ale zamiast zwrotu mockInputStream, można po prostu wrócić new ByteArrayInputStream("{foo : 'bar'}".getBytes())

Wreszcie, można sprawdzić, czy obiekt ma odpowiedzi json „foo” właściwość, która ma wartość „bar”.

To powiedziawszy, nie jestem pewien, czy dana metoda jest warta przetestowania - ponieważ wszystko to otwiera strumienie i odczytuje dane.

0

Najpierw zrozum znaczenie Mocking.

1) Dlaczego potrzebujemy kpiny?

Załóżmy, że nie chcemy wywoływać żadnej oryginalnej metody i chcemy, aby zamiast tej oryginalnej metody, którą powinniśmy nazwać metodą sztuczną, powinniśmy pójść na kpiny.

Na przykład:

Mockito.when(mockHttpClient.execute(mockHttpPost)).thenReturn(mockHttpResponse) 

Oznacza to, ilekroć ten execute() będzie nazwany potem wrócisz własną przygotowaną wartość zamiast oryginalnego mockHttpResponse.

W twoim przypadku przygotuj swój obiekt pośredni i zakpić, jeśli tego potrzebujesz. Tutaj przygotowujesz swoją odpowiedź (Uwaga aktualna, ale manekin).

mockHttpResponse.setEntity(new Entity()); 
mockHttpResponse.getEntity().setContent('{yourJsonString}'); 

Jeśli więc Twój

mockHttpClient.execute(mockHttpPost); //will be called 

Następnie zwróci odpowiedź, że przygotowane w metodzie badania ręcznie.

Gdy kontrola przychodzi do

new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 

Wtedy dostaniesz {yourJsonString} gdy response.getEntity().getContent() nazywa i niech reszta kodu zrobić jego funkcjonalność. Na końcu twój uparty obiekt JSON zostanie przygotowany.

Pamiętaj przypadki testowe są tylko dla programistów help.We można drwić niczego i niczego ani żadnej object.Just skrótową piszemy przypadku test powrócić do zapoznania się z naszą przepływ sterowania przez przepuszczenie oczekiwano, a nie oczekiwane wartości.

Ułatwi to twoją pracę. Teraz chcesz sfałszować swoją klasę BufferReader.

BufferedReader bufferedReader = org.mockito.Mockito.mock(BufferedReader.class); 
when(bufferedReader.readLine()).thenReturn("first line").thenReturn("second line"); 

org.junit.Assert.when(new Client(bufferedReader).parseLine()).thenEquals(IsEqual.equalTo("1")); 
+0

Cześć Shoaib, dzięki za wyjaśnienia !! Nie jestem pewien, co należy tutaj zrobić, ale staram się uniknąć wykonywania rzeczywistego wywołania HttpClient, ponieważ mam ostatnią przetworzoną (przeanalizowaną) wersję odpowiedzi z tego wywołania, która jest obiektem JSON, który utworzyłem. Radzę .. Dzięki –

+0

Sprawdź zaktualizowany kod –

+0

Jest to bardzo pomocne. Ale jak wspomniałem powyżej w moim pytaniu, zwracam mockHttpResponse, gdy wywoływana jest odpowiedź HttpResponse = defaultHttpClient.execute (postRequest). Ale w rzeczywistej metodzie, muszę wykonać 3 kroki przed zwróceniem obiektu JSON. Tak więc, gdybym miał zwrócić zwrócony obiekt JSON, gdy uruchomiono metodę response.getEntity(). GetContent(), czy to nie będzie problem, gdy uruchomione zostaną późniejsze instrukcje w mojej oryginalnej metodzie? Proszę doradzić .. –

6

Ty może trzeba kpić HttpClient i HttpResponse, jeśli są interfejsy (choć, w zależności od swojej biblioteki, można użyć MockHttpClient lub MockHttpResponse), ale nie powinno być szyderczy niczego innego .

Dlaczego?

The mock ustala oczekiwane zachowanie wyjściowe na klasach, które nie mogą być konkretne, a raczej klasy, które chcemy zachowywać się w określony sposób dla tego konkretnego wystąpienia testu. Chcesz się upewnić, że odzyskasz poprawną odpowiedź ze strony próbnej HttpClient, a gdy zostanie wywołana response.getEntity(), to zwróci ona znaczącą wartość HttpEntity. Możesz wybrać kpiny z tego, albo nie; Osobiście nie chciałbym, ponieważ próbka nie dodaje żadnej dodatkowej wartości (chyba że weryfikuje, że określona metoda została wywołana).

Cała reszta to konkretna implementacja - powinieneś pozwalać innym obiektom wchodzić w interakcje z rezultatami wcześniej wyśmianych elementów, aby zapewnić, że zachowują się tak, jakby były, gdyby nie było makiet.

Właściwie ... naprawdę nie można z nich kpić, chyba że je przekażesz lub wstrzykniesz w jakiś sposób. Zrobiłbym zdecydowanie zniechęcaj się do próby sfałszowania jakichkolwiek obiektów ed w tej metodzie new.

Nie określasz, co twierdzisz, ale spodziewam się, że w pewnym stopniu jest to Twoja JSONObject. Twierdziłbym, że to, co oczekiwaliście, że zostaniecie w nim umieszczeni, faktycznie trafiło do obiektu JSON, a także sprawdziło, czy wyśmiewane obiekty zostały wywołane i wywołane w sposób, jaki oczekiwaliście.

adnotacji @Mock nie jest kaskadowy, nawiasem mówiąc - trzeba opisywać wszystkie pola szydzili z @Mock, następnie albo opisywanie klasę testową z @RunWith(MockitoJunitRunner.class) lub użyj MockitoAnnotation.initMocks(this) (jedna lub druga, obie nie są wymagane, chyba że na mocy przypadki skrajne). Jeśli wybierzesz adnotacje, nie zapomnij o @InjectMocks na swoim obiekcie testowym.

Na koniec twoje warunki robią to, czego oczekiwałbym od nich - powinny być w porządku.

Powiązane problemy