【问题标题】:Mockito pattern for a Spring web service call用于 Spring Web 服务调用的 Mockito 模式
【发布时间】:2013-04-18 11:22:58
【问题描述】:

我的测试类有这个方法

public SomeWebServiceResponse callDownstream(SomeWebServiceRequest request)  {
    return (SomeWebServiceResponse ) super.callService(request);
}

super 方法只是调用 Spring WS 进行调用 - 以简化形式

response = getWebServiceTemplate().marshalSendAndReceive(this.getBaseURL(), 
    request);
return response;

当我编写单元测试时,它会尝试进行实际的 Web 服务调用。我不清楚如何模拟这个,或者更确切地说我们应该模拟什么。

我是否应该从文件系统加载示例响应并在其中查找一些字符串 - 在这种情况下,我只是在测试文件加载。

实际调用在基类中,我知道我们不能只模拟那个方法。有什么指点吗?

【问题讨论】:

    标签: java junit mockito spring-ws


    【解决方案1】:

    Spring 还提供了用于模拟 Web 服务服务器以及来自客户端的请求的工具。 Spring WS manual 中的第 6.3 章展示了如何进行模拟。

    Spring WS 模拟工具改变了 Web 服务模板的行为,因此您可以在超类中调用该方法 - 然后该方法将调用 Spring Mock 服务服务器。

    这是一个使用 Spring 模拟服务服务器的示例单元测试:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration({"classpath:spring-ws.xml"})
    public class SetStatusFromSrsTemplateTest {
        @Autowired
        private WebServiceTemplate wsTemplate;
    
        @Before
        public void setUp() throws Exception {
            mockServer = MockWebServiceServer.createServer(wsTemplate);
        }
    
        @Test
        public void testCall() {
            SomeWebServiceRequest sampleRequest = new SomeWebServiceRequest();
            // add properties to the sampleRequest...
            Source expectedPayload = new ResourceSource(new ClassPathResource("exampleRequest.xml"));
            Source expectedResponse = new ResourceSource(new ClassPathResource("exampleResponse.xml"));
            mockServer.expect(payload(expectedPayload)).andRespond(withPayload(expectedResponse));
            instance.callDownStream(sampleRequest);
            mockServer.verify();
        }
    }
    

    上面的示例将使模拟服务服务器只期望一个具有给定负载的请求,并且(如果接收到的负载与预期负载匹配)以给定的响应负载响应。

    但是,如果您只想验证在测试期间是否真的调用了超类中的方法,并且您对该调用之后的消息交换不感兴趣,则应该使用 Mockito。

    如果您想使用 Mockito,我建议使用间谍(另请参阅 Kamlesh 的回答)。例如

    // Decorates this with the spy.
    MyClass mySpy = spy(this);
    // Change behaviour of callWebservice method to return specific response
    doReturn(mockResponse).when(mySpy).callWebservice(any(SomeWebServiceRequest.class));
    // invoke the method to be tested.
    instance.callDownstream(request);
    // verify that callWebService has been called
    verify(mySpy, times(1)).callWebService(any(SomeWebServiceRequest.class));
    

    【讨论】:

    • 对不起我之前的评论。我想我不太明白这个问题。我将提供一个示例如何使用 Spring 模拟服务服务器进行单元测试。
    • 模拟整个 Web 服务,包括发送和接收消息(第一个代码示例)实际上不仅仅是一个单元测试——它是一个集成测试,正如引用的 Spring 手册所指出的那样。如果您只需要一个单元测试,那么您应该坚持使用 Mockito(第二个代码示例)。
    • 我收到 java.lang.AssertionError:预期有进一步的连接。知道如何解决这个问题吗?
    【解决方案2】:

    正如@Duncan 所说,如果可以的话,使用依赖注入进行组合是一种可行的方法,然后模拟该依赖项。

    如果你不能,那么你可以使用 mockito spy 选择性地模拟 class under test 的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-17
      • 2013-06-06
      • 2015-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-20
      相关资源
      最近更新 更多