迈克尔的回答非常接近,但这是一个有效的例子。
我已经在我的单元测试中使用了 Mockito,所以我对这个库很熟悉。然而,与我之前使用 Mockito 的经验不同,简单地模拟返回结果并没有帮助。我需要做两件事来测试所有用例:
- 修改 StreamResult 中存储的值。
- 引发 SoapFaultClientException。
首先,我需要意识到我不能用 Mockito 模拟 WebServiceTemplate,因为它是一个具体的类(如果这是必要的,你需要使用 EasyMock)。幸运的是,对 Web 服务 sendSourceAndReceiveToResult 的调用是 WebServiceOperations 接口的一部分。这需要更改我的代码以期望 WebServiceOperations 与 WebServiceTemplate。
以下代码支持在 StreamResult 参数中返回结果的第一个用例:
private WebServiceOperations getMockWebServiceOperations(final String resultXml)
{
WebServiceOperations mockObj = Mockito.mock(WebServiceOperations.class);
doAnswer(new Answer()
{
public Object answer(InvocationOnMock invocation)
{
try
{
Object[] args = invocation.getArguments();
StreamResult result = (StreamResult)args[2];
Writer output = result.getWriter();
output.write(resultXml);
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
}).when(mockObj).sendSourceAndReceiveToResult(anyString(), any(StreamSource.class), any(StreamResult.class));
return mockObj;
}
对第二个用例的支持类似,但需要抛出异常。以下代码创建了一个包含 faultString 的 SoapFaultClientException。faultCode 由我正在测试的处理 Web 服务请求的代码使用:
private WebServiceOperations getMockWebServiceOperations(final String faultString)
{
WebServiceOperations mockObj = Mockito.mock(WebServiceOperations.class);
SoapFault soapFault = Mockito.mock(SoapFault.class);
when(soapFault.getFaultStringOrReason()).thenReturn(faultString);
SoapBody soapBody = Mockito.mock(SoapBody.class);
when(soapBody.getFault()).thenReturn(soapFault);
SoapMessage soapMsg = Mockito.mock(SoapMessage.class);
when(soapMsg.getSoapBody()).thenReturn(soapBody);
doThrow(new SoapFaultClientException(soapMsg)).when(mockObj).sendSourceAndReceiveToResult(anyString(), any(StreamSource.class), any(StreamResult.class));
return mockObj;
}
这两个用例可能需要更多代码,但它们适用于我的目的。