Add a slice @WebServiceClientTest annotation that can be used when testing SOAP clients.

The implementation is quite similar to @RestClientTest but for WebServiceTemplateBuilder. PR is not ready yet, it is just a concept of how it could be.

Here is a small example of usage:

@WebServiceClientTest(ExampleWebServiceClient.class)
class WebServiceClientIntegrationTests {

    @Autowired
    private MockWebServiceServers servers;

    @Autowired
    private ExampleWebServiceClient client;

    @Test
    void mockServerCall() {
        this.servers.expect(RequestMatchers.payload(new StringSource("<request/>"))).andRespond(
                ResponseCreators.withPayload(new StringSource("<response><status>200</status></response>")));
        assertThat(this.client.test()).extracting(Response::getStatus).isEqualTo(200);
    }

    @Test
    void mockServerCall1() {
        this.servers.expect(RequestMatchers.connectionTo("https://example1"))
                .andRespond(ResponseCreators.withPayload(new StringSource("<response/>")));
        assertThatExceptionOfType(SourceAssertionError.class).isThrownBy(this.client::test)
                .withMessageContaining("Unexpected connection expected");
    }
}

If you are interested in this feature I will add more tests and documentation.

Also, pay attention to https://github.com/spring-projects/spring-boot/compare/master...nosan:webservice-client-test?expand=1#diff-a0ae2b770ccb1b5cc0b45d9966df843aR66 it would be nice to have reset() functionality in MockWebServiceServer class. Is it possible to add?

Let me know what you think and thanks in advance.

P.S. Work-in-Progress

Comment From: philwebb

@nosan This looks like a really nice addition to the existing test slice support and would be great to add it in 2.2.x. The one things we're not totally sure about is the MockWebServiceServers class. I think we'd rather not introduce that in Boot and instead just support a single MockWebServiceServer (similar to the way we support MockRestServiceServer).

it would be nice to have reset() functionality in MockWebServiceServer class. Is it possible to add?

@gregturn Can probably help answer that. I'd certainly like to keep a clean separation and have the general use Mock code in spring-ws and keep the Boot code specific to our slice concepts.

Comment From: nosan

Thank you @philwebb, I have added MockWebServiceServers because I have not found a way to customize MockWebServiceServer with a custom MockWebServiceMessageSender to create a deferred MockWebServiceServer since MockWebServiceMessageSender has a package private modifier.

If adding support for a slice @WebServiceClientTest annotation is desired, then the possibility to reset MockWebServiceServer after each test should be added. Also, a public modifier to MockWebServiceMessageSender class should be added as well.

Comment From: nosan

@philwebb I've updated PR https://github.com/spring-projects/spring-boot/pull/17274/commits/fc53f37bb68bfed45a41ff9b78f9ac20cb7409a7 to support only a single WebServiceTemplate.

This approach is quite messy with Reflection for me. I would rather not to add @WebServiceClientTest annotation at all than using this way.

I am hoping that spring-ws team could help here.

Comment From: philwebb

@nosan I totally agree, we'll really need some upstream changes I think.

Comment From: wilkinsona

@gregturn can you please review the discussion above? As currently proposed, there's quite a bit of reflection when interacting with Spring Web Services which we'd like to avoid.

Comment From: gregturn

I don't see why we can't alter the visibility of MockWebServiceServer(MockWebServiceMessageSender). Looks like a valid use case to open it up for public usage.

I opened https://jira.spring.io/browse/SWS-1085.

Comment From: gregturn

You can test out these changes using 2.4.7.BUILD-SNAPSHOT or 3.0.9.BUILD-SNAPSHOT (until a release is made).

Comment From: gregturn

If @nosan wishes to retool the PR using these modifications, so be it.

Comment From: nosan

Thanks for your feedback and changes, @gregturn

I checked 3.0.9.BUILD-SNAPSHOT and unfortunately, those changes are not enough to avoid reflection at all.

Could you please add the following changes?

  • MockWebServiceMessageSender must be public as well.
  • Add reset method to MockWebServiceServer, similar to verify but for reset.

'reset' just clearsexpectedConnections and sets connectionIterator to null.

Ideally, this class should be removed.

Thanks in advance

Comment From: gregturn

I can extend the surface API to support a reset, but are you sure you can't just create a new instance for each test case?

Comment From: wilkinsona

@gregturn In the proposed changes, MockWebServiceServer is being used as a bean. Requiring a new instance per test would mean that we needed a new application context per test, making the test framework's context cache redundant and slowing down overall test execution.

Comment From: gregturn

@nosan Okay, the additional changes you requested have been applied. Again, check the latest snapshots and see if they are suitable.

Comment From: nosan

Thanks @gregturn

PR has been updated

Comment From: gregturn

Spring WS 3.0.9.RELEASE has been released.

Comment From: wilkinsona

Re-opening to address the CI failures on JDK 11 and 14.

Comment From: nosan

Thanks a lot! 👍