2009-04-30 12 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); 

何私のコードに示すことであるI「マイクロテスト」がかかるオブジェクト。それは私のテストで私の生産的なコードを実装するようなものです。結果xmlの例はLondon on GeoNamesです。 私の意見では、それはあまりに細かすぎます。

しかし、私はeverystepを与えずにWebサービスを模擬することができますか?モックオブジェクトにXMLファイルを返すだけでいいですか?

コードに関するものではなく、のアプローチです。

私はあなたが本当に結果を使用するコードにWebサービスから返された結果をあざけることにしたいのJUnit 4.xとMockito 1.7

答えて

1

を使用しています。上のサンプルコードでは、mDocumentを嘲笑しているようですが、実際にはあなたのwebserviceの模擬インスタンスから返されたmDocumentのインスタンスを渡して、geoLocationFetcherから返されたlocationBeanがA_LOCATION_BEANの値と一致することを確認してください。

+1

ありがとうございました。だから、あなたはどのように "ウェブサービスを模倣する"でしょうか? – guerda

+1

通常、私はインターフェイスを宣言し、インターフェイスを実装し、Webサービスをインスタンス化するWebサービスラッパーを作成します。 – lomaxx

+0

結果を確認するだけで、Webサービスのコンシューマーが返しますか? – guerda

2

ここで本当の問題は、モック1を挿入するのが難しいため、Webサービスを呼び出して作成するシングルトンがあることだと思います。

シングルトンクラスに(おそらくパッケージレベルの)アクセスを追加する必要があります。たとえば、コンストラクタが

private GeoLocationFactory(WebService service) { 
    ... 
} 

のように見える場合は、コンストラクタパッケージレベルを作成し、模擬Webサービスで作成することができます。

また、変更可能なシングルトンが好きではありませんが、セッターメソッドを追加してWebサービスを設定することもできます。またその場合は、Webサービスの設定を解除する必要があります。

メソッドでWebサービスを作成する場合は、GeoLocationFactoryを拡張可能にしてモックサービスを置き換える必要があります。

また、シングルトン自体を削除することもできます。オンラインで、おそらくこれを行う方法に関する記事があります。

1

最も簡単なオプションは、ファイルシステムからの応答XMLを読み取るために、コードを変更することができ

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

、Webサービスクライアントを模擬することであろう。

サンプルコードはここにあります:Mocking .NET WebServices with Mockito