2013-12-13 86 views
6

我有存根的JSON對象,但需要模擬以下使用的Mockito:使用的Mockito用於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()); 

我創建了以下嘲笑:

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

,並具有以下when聲明:

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

問題:我是否需要創建所有這些'when'statem如果是的話,那麼我需要創建哪些其他內容以便能夠訪問被截斷的JSON?

任何建議請問?

感謝

+0

請添加一些代碼,以便我們可以瞭解確切的模擬對象 –

+0

您是否在使用Spring MVC之類的任何Web框架? – SergeyB

回答

1

是的,你可能需要的所有語句,你所提到的時候。 但不是返回mockInputStream,而是返回new ByteArrayInputStream("{foo : 'bar'}".getBytes())

最後,您可以驗證json響應對象是否具有'bar'屬性的'foo'屬性。

這就是說,我不知道該給定的方法是否值得測試 - 因爲所做的只是打開的流和讀取數據。

0

先了解Mocking意義。

1)爲什麼我們需要嘲笑?

假設我們不希望任何調用原始的方法,並希望這樣的而不是原來的方法,我們應該調用虛擬方法,那麼我們就應該去嘲諷。

對於e.g:

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

這意味着每當這個​​將被調用,那麼您將回到自己準備的價值,而不是原來的mockHttpResponse

因此,在你的情況下準備你的存根對象和mockit,如果你需要的話。 在這裏你準備你的迴應(注意實際但虛擬)。

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

所以每當你

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

然後,它會返回您在測試方法手工製作的響應。

當你的控制來

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

然後你會得到{yourJsonString}response.getEntity().getContent()被調用,並讓其餘的代碼做它的功能。最後你的JSON stubbed對象將被準備好。

記住測試用例只是開發商help.We可以模擬任何東西,返回任何東西或任何存根object.Just我們寫測試用例通過將預期和非預期值來檢查我們的控制流。

這將使你的工作變得簡單。現在你想模擬你的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

嗨Shoaib,感謝您的澄清!不知道在這裏需要做什麼,但我試圖避免做一個實際的HttpClient調用,因爲我有這個調用的最終處理(Parsed)版本的響應,這是一個JSON對象,我已被stubbed。請告知..謝謝 –

+0

請檢查更新的代碼 –

+0

這是非常有用的。但正如我在我的問題中提到的,當HttpResponse響應= defaultHttpClient.execute(postRequest)被調用時,我返回一個mockHttpResponse。但是在實際的方法中,我必須在返回JSON對象之前執行3個步驟。因此,如果我在運行response.getEntity()。getContent()時返回存根JSON對象,那麼當我的原始方法中後面的語句運行時,這不會成爲問題嗎?請指教.. –

6

可能有嘲笑HttpClientHttpResponse,如果他們是接口(雖然,這取決於你的圖書館,你可以使用MockHttpClientMockHttpResponse),但你不應被嘲笑別的。

爲什麼?

該模擬是建立預期的輸出行爲,我們不能具體,或者更確切地說,我們希望以特定的方式表現這個特定的測試實例的類。您希望確保您從模擬HttpClient得到正確的回覆,並且在調用response.getEntity()時,它會返回有意義的HttpEntity。你可以選擇嘲笑或不嘲笑;我個人不會這樣做,因爲模擬不會增加任何額外的值(除了可能驗證某個特定的方法被調用)。

其他一切都是一個具體的實現 - 你應該允許其他對象與之前模擬元素的結果進行交互,以確保它們的行爲與沒有模擬時一樣。其實......你真的不能嘲笑那些人,除非你通過他們或以某種方式注入他們。我會強烈勸阻你試圖嘲笑在該方法中的任何new ed對象。

您沒有指定您所聲稱的內容,但我認爲這是您的某些容量的JSONObject。我會斷言你期望放入它的內容實際上已經將它放入JSON對象中,並且確認你的模擬對象是以你期望的方式被調用和調用的。

你的註釋@Mock沒有級聯,順便說一句 - 你必須標註全部嘲笑領域與@Mock,然後要麼@RunWith(MockitoJunitRunner.class)註釋測試類,或者使用MockitoAnnotation.initMocks(this)(一方或另一方,雙方不需要下除外邊緣情況)。如果您選擇註釋,請不要忘記測試對象上的@InjectMocks

最後,你的when條件做我期望他們做的 - 這些應該沒問題。