迈克尔的回答非常接近,但这是一个有效的例子。
我已经在我的单元测试中使用了 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;
}
这两个用例可能需要更多代码,但它们适用于我的目的。