【发布时间】:2014-05-07 05:17:41
【问题描述】:
我正在尝试对尝试隐藏所有 Web 服务实现细节的 Web 服务包装类进行单元测试。它是从脚本平台调用的,因此所有接口都是简单的字符串或整数。该类提供了一个静态初始化方法,该方法采用主机名和端口号,并使用它来创建私有静态 Apache CXF IRemote 端口实例(从 CXF wsdl2java 生成)。随后调用静态业务方法委托给端口实例。
在对静态包装类进行单元测试时,如何使用 JMockit 模拟 CXF 端口存根?
public class WebServiceWrapper {
private static final QName SERVICE_NAME = new QName("http://www.gwl.org/example/service",
"ExampleService");
private static IRemoteExample _port = null;
public static final String initialise(String url) {
if(_port != null) return STATUS_SUCCESS;
try {
URL wsdlURL = new URL(url);
ExampleService svc = new ExampleService(wsdlURL, SERVICE_NAME);
_port = svc.getIRemoteExamplePort();
BindingProvider bp = (BindingProvider)_port;
Map<String, Object> context = bp.getRequestContext();
context.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);
return STATUS_SUCCESS;
}
catch(MalformedURLException ex) {
return STATUS_ERROR_PREFIX + ex.getMessage();
}
catch(WebServiceException ex) {
return STATUS_ERROR_PREFIX + ex.getMessage();
}
}
public static final String businessMethod(String arg) {
if(_port == null) {
return STATUS_ERROR_PREFIX + "Attempted to call businessMethod before connection is initialised. Pease call initialise first.";
}
try {
BusinessMethodRequest request = new BusinessMethodRequest ();
BusinessThing thing = new BusinessThing();
thing.setValue(arg);
request.setThing(thing);
BusinessMethodResponse response = _port.businessMethod(request);
String result = response.getResult();
if(result == null) {
return STATUS_ERROR_PREFIX + "Null returned!";
}
return STATUS_SUCCESS;
}
catch(MyBusinessException_Exception ex) {
return STATUS_ERROR_PREFIX + ex.getFaultInfo().getReason();
}
catch(WebServiceException ex) {
return STATUS_ERROR_PREFIX + ex.getMessage();
}
}
Web 服务的示例行为是,如果我传递值“OK”,那么它会返回一条成功消息,但如果我使用“DUPLICATE”值调用,那么 Web 服务将抛出 MyBusinessException_Exception。
我想我已经设法模拟了 _port 对象,但是业务调用总是返回一个 null Response 对象,所以我怀疑我的 Expectations 没有正确定义“BusinessThing”对象。到目前为止我的测试方法。
@Test
public void testBusinessMethod(@Mocked final IRemoteExample port) {
new NonStrictExpectations() {
@Capturing IRemoteExample port2;
{
BusinessThing thing = new BusinessThing();
thing.setValue("OK");
BusinessMethodRequest req = new BusinessMeothdRequest();
req.setThing(thing);
BusinessMethodResponse resp = new BusinessMethodResponse ();
resp.setResult("SUCCESS");
try {
port.businessMethod(req);
returns(resp);
}
catch(MyBusinessException_Exception ex) {
returns(null);
}
Deencapsulation.setField(WebServiceWrapper.class, "_port", port);
}
};
String actual = WebServiceWrapper.businessMethod("OK");
assertEquals(WebServiceWrapper.STATUS_SUCCESS, actual);
}
【问题讨论】:
-
我想我快到了。我认为我的期望与传入的请求对象的特定实例不匹配。看起来我需要为我的 BusinessMethodRequest 对象提供一个自定义匹配器,它只关心 request.getThing().getValue() 如果可以这样做有内置匹配器,请大喊。
标签: unit-testing cxf webservice-client jmockit