简体   繁体   English

Spring Web服务调用的Mockito模式

[英]Mockito pattern for a Spring web service call

My class under test has this method 我的班级有这种方法

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

the super method is just a call to Spring WS to make the call - in simplified form super方法只是调用Spring WS来进行调用 - 以简化形式

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

When I write a unit test it tried to make an actual web service call. 当我编写单元测试时,它试图进行实际的Web服务调用。 I'm not clear how to mock this or rather what we should be mocking. 我不清楚如何嘲笑这个或者更确切地说我们应该嘲笑什么。

Should I be loading a sample response from filesystem and looking for some string in it - in that case I'm only testing file loading. 我应该从文件系统加载一个示例响应并在其中查找一些字符串 - 在这种情况下,我只测试文件加载。

The actual call is in base class and I know we can't mock only that method. 实际调用是在基类中,我知道我们不能只模拟该方法。 Any pointers? 有什么指针吗?

Spring does also provide facilities for mocking web service servers as well as requests from clients. Spring还提供了用于模拟Web服务服务器以及来自客户端的请求的工具。 The chapter 6.3 in the Spring WS manual shows how to do mocking. Spring WS手册中的第6.3章介绍了如何进行模拟。

The Spring WS mocking facility changes the behaviour of the Web Service Template, so you can call that method in the super-class - that method would then call the Spring Mock Service Server. Spring WS模拟工具改变了Web服务模板的行为,因此您可以在超类中调用该方法 - 该方法将调用Spring Mock Service Server。

Here is a sample unit test with the Spring mock service server: 以下是使用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();
    }
}

The above example will make the mock service server expect exactly one request with the given payload and (if the payload received matches the expected payload) respond with the given response payload. 上面的示例将使模拟服务服务器完全期望具有给定有效载荷的一个请求和(如果接收的有效载荷与预期的有效载荷匹配)响应给定的响应有效载荷。

However, if you only want to verify that the method in the super-class is really called during the test and if you're not interested in the message exchange following that call, you should use Mockito. 但是,如果您只想验证在测试期间是否真正调用了超类中的方法,并且如果您对该调用后的消息交换不感兴趣,则应使用Mockito。

If you'd like to use Mockito, I'd suggest the spy (see also Kamlesh's answer). 如果您想使用Mockito,我会建议间谍(另见Kamlesh的回答)。 Eg 例如

// 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));

As @Duncan said composition with dependency injection would be a way to go if you can and then mock that dependency. 正如@Duncan所说,如果你可以然后嘲笑那种依赖,那么使用依赖注入的组合将是一种方法。

If you can't then you can selectively mock the methods of class under test using mockito spy . 如果你不能,那么你可以使用mockito spy选择性地模拟被测类的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM