2009-04-30 93 views
1

我正在實現一個使用web服務的客戶端。我想減少依賴關係,並決定模擬web服務。
我使用mockito,與EasyMock相比,它能夠模擬類而不僅僅是接口。但那不是重點。模擬web服務的策略

在我的測試中,我得到這個代碼:

// Mock the required objects 
Document mDocument = mock(Document.class); 
Element mRootElement = mock(Element.class); 
Element mGeonameElement = mock(Element.class); 
Element mLatElement = mock(Element.class); 
Element mLonElement = mock(Element.class); 

// record their behavior 
when(mDocument.getRootElement()).thenReturn(mRootElement); 
when(mRootElement.getChild("geoname")).thenReturn(mGeonameElement); 
when(mGeonameElement.getChild("lat")).thenReturn(mLatElement); 
when(mGeonameElement.getChild("lon")).thenReturn(mLonElement); 
// A_LOCATION_BEAN is a simple pojo for lat & lon, don't care about it! 
when(mLatElement.getText()).thenReturn(
    Float.toString(A_LOCATION_BEAN.getLat())); 
when(mLonElement.getText()).thenReturn(
    Float.toString(A_LOCATION_BEAN.getLon())); 

// let it work! 
GeoLocationFetcher geoLocationFetcher = GeoLocationFetcher 
    .getInstance(); 
LocationBean locationBean = geoLocationFetcher 
    .extractGeoLocationFromXml(mDocument); 

// verify their behavior 
verify(mDocument).getRootElement(); 
verify(mRootElement).getChild("geoname"); 
verify(mGeonameElement).getChild("lat"); 
verify(mGeonameElement).getChild("lon"); 
verify(mLatElement).getText(); 
verify(mLonElement).getText(); 

assertEquals(A_LOCATION_BEAN, locationBean); 

什麼我的代碼顯示的是我「微測試」的消費對象。這就像我將在我的測試中實現我的高效代碼。結果xml的一個例子是London on GeoNames。 在我看來,它太細緻。

但是,我怎樣才能嘲笑一個web服務而不給永久?我應該讓模擬對象返回一個XML文件嗎?

這不是代碼,而是方法

我使用JUnit 4.x和1.7的Mockito

回答

1

你真的想被嘲諷從web服務將使用結果的代碼返回的結果。在上面的示例代碼中,您似乎在嘲笑mDocument,但您確實想要傳入已從Web服務的模擬實例返回的mDocument實例,並聲明從geoLocationFetcher返回的locationBean與A_LOCATION_BEAN的值相匹配。

+1

謝謝,我明白了你的觀點。那麼你會如何「嘲笑web服務」? – guerda 2009-04-30 06:08:18

2

我認爲這裏真正的問題是你有一個調用和創建Web服務的單例,所以很難插入一個模擬的。

您可能需要添加(可能包級別)訪問單例類。例如,如果構造器看起來像

private GeoLocationFactory(WebService service) { 
    ... 
} 

您可以使構造函數包級別,並創建一個與模擬Web服務。

或者,您可以通過添加setter方法來設置webservice,儘管我不喜歡可變單例。同樣在這種情況下,你必須記得在之後取消設置web服務。

如果webservice是在一個方法中創建的,您可能必須使GeoLocationFactory可擴展以替代模擬服務。

您也可以考慮刪除單身人士本身。網上有文章,可能在這裏如何做到這一點。

1

最簡單的辦法是嘲笑的WebService客戶端,

when(geoLocationFetcher.extractGeoLocationFromXml(anyString())) 
    .thenReturn("<location/>"); 

您可以修改代碼來讀取文件系統響應XML。

示例代碼可以在這裏找到:Mocking .NET WebServices with Mockito