Web services 模拟Web服务的策略
我正在实现一个使用Web服务的客户端。我想减少依赖性,并决定模拟Web服务。Web services 模拟Web服务的策略,web-services,unit-testing,junit,mocking,mockito,Web Services,Unit Testing,Junit,Mocking,Mockito,我正在实现一个使用Web服务的客户端。我想减少依赖性,并决定模拟Web服务。 我使用的是,与EasyMock相比,它的优势在于能够模拟类,而不仅仅是接口。但这不是重点 在我的测试中,我得到了以下代码: // Mock the required objects Document mDocument = mock(Document.class); Element mRootElement = mock(Element.class); Element mGeonameElement = mock(El
我使用的是,与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的一个示例是。
在我看来,它太细了
但是我怎么能在不给everystep的情况下模仿Web服务呢?我应该让模拟对象只返回一个XML文件吗
这不是关于代码,而是关于方法
我使用的是JUnit 4.x和Mockito 1.7,您真的希望模拟从Web服务返回的结果到将使用结果的代码。在上面的示例代码中,您似乎在模拟mDocument,但您确实希望传入一个mDocument实例,该实例是从您的Web服务的模拟实例返回的,并断言从geoLocationFetcher返回的locationBean与某个位置BEAN的值匹配。您确实希望模拟返回的结果吗从webservice到将使用结果的代码。在上面的示例代码中,您似乎在模拟mDocument,但您确实希望传入一个mDocument实例,该实例已从您的Web服务的模拟实例返回,并断言从geoLocationFetcher返回的locationBean与某个位置BEAN的值相匹配。我认为这里真正的问题是您有一个调用并创建web服务的singleton,因此很难插入模拟服务 您可能必须向singleton类添加(可能是包级)访问权限。例如,如果构造函数看起来像
private GeoLocationFactory(WebService service) {
...
}
您可以将构造函数包设置为级别,只需使用模拟的web服务创建一个构造函数包
或者,您可以通过添加setter方法来设置webservice,尽管我不喜欢可变单例。在这种情况下,您还必须记得在之后取消设置Web服务
如果webservice是在方法中创建的,则可能必须使GeoLocationFactory可扩展以替换模拟服务
您还可以研究删除单例本身。网上有很多文章,这里可能也有关于如何做到这一点的文章。我认为这里真正的问题是,您有一个调用并创建web服务的单例,因此很难插入一个模拟的单例 您可能必须向singleton类添加(可能是包级)访问权限。例如,如果构造函数看起来像
private GeoLocationFactory(WebService service) {
...
}
您可以将构造函数包设置为级别,只需使用模拟的web服务创建一个构造函数包
或者,您可以通过添加setter方法来设置webservice,尽管我不喜欢可变单例。在这种情况下,您还必须记得在之后取消设置Web服务
如果webservice是在方法中创建的,则可能必须使GeoLocationFactory可扩展以替换模拟服务
您还可以研究删除单例本身。网上有很多文章,这里可能有关于如何做到这一点的文章。最简单的选择是模拟WebService客户端
when(geoLocationFetcher.extractGeoLocationFromXml(anyString()))
.thenReturn("<location/>");
when(geoLocationFetcher.extractGeoLocationFromXml(anyString()))
。然后返回(“”);
您可以修改代码以从文件系统读取响应xml
示例代码可以在这里找到:最简单的选择是模拟WebService客户端
when(geoLocationFetcher.extractGeoLocationFromXml(anyString()))
.thenReturn("<location/>");
when(geoLocationFetcher.extractGeoLocationFromXml(anyString()))
。然后返回(“”);
您可以修改代码以从文件系统读取响应xml
示例代码可以在这里找到:谢谢,我明白你的意思了。那么你会如何“模拟Web服务”?通常我会声明一个接口并创建一个Web服务包装器来实现该接口并实例化Web服务,所以你只要检查结果,你的Web服务消费者就会返回?谢谢,我明白你的意思了。那么,您将如何“模拟Web服务”?通常我会声明一个接口并创建一个实现该接口并实例化Web服务的Web服务包装器,这样您只需检查结果,您的Web服务使用者就会返回?