Webサービスをモックする戦略
-
03-07-2019 - |
質問
Webサービスを使用するクライアントを実装しています。依存関係を減らしたいので、ウェブサービスをモックすることにしました。
mockito を使用していますが、クラスをモックできるのではなく、EasyMockに対して利点があります。ただインターフェイス。しかし、それはポイントではありません。
テストでは、次のコードがあります:
// 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の例は、 GeoNamesのロンドンです。 私の意見では、あまりにもきめ細かすぎます。
しかし、どうすればすべてのステップを与えずにWebサービスをモックできますか?モックオブジェクトがXMLファイルを返すようにする必要がありますか?
コードに関するものではなく、アプローチです。
JUnit 4.xおよびMockito 1.7を使用しています
解決
本当に、Webサービスから返された結果を、結果を使用するコードにモックしたいのです。上記のサンプルコードでは、mDocumentをモックしているようですが、Webサービスのモックされたインスタンスから返されたmDocumentのインスタンスを渡し、geoLocationFetcherから返されたlocationBeanがA_LOCATION_BEANの値と一致することをアサートします。
他のヒント
ここでの本当の問題は、Webサービスを呼び出して作成するシングルトンがあるため、モックサービスを挿入することが難しいことです。
シングルトンクラスへのアクセス(おそらくパッケージレベル)を追加する必要がある場合があります。たとえば、コンストラクタが次のように見える場合
private GeoLocationFactory(WebService service) {
...
}
コンストラクターパッケージレベルを作成し、モックされたWebサービスでコンストラクターパッケージを作成できます。
代わりに、セッターメソッドを追加してWebサービスを設定できますが、可変シングルトンは好きではありません。また、その場合は、後でWebサービスを設定解除することを忘れないでください。
Webサービスがメソッドで作成されている場合、GeoLocationFactoryを拡張可能にして、模擬サービスに置き換える必要がある場合があります。
シングルトン自体を削除することもできます。オンラインの記事があり、おそらくその方法についてはここにあります。
最も簡単なオプションは、WebServiceクライアントをモックすることです
when(geoLocationFetcher.extractGeoLocationFromXml(anyString()))
.thenReturn("<location/>");
コードを変更して、ファイルシステムから応答xmlを読み取ることができます。
サンプルコードは次の場所にあります。 .NETのモックMockitoを使用したWebサービス