Skip to content

Commit fc53f37

Browse files
committed
Update @WebServiceClientTest to support only a single WebServiceTemplate.
1 parent 80157a1 commit fc53f37

17 files changed

+183
-370
lines changed

spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/webservices/client/AutoConfigureMockWebServiceServer.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
2727
import org.springframework.boot.test.autoconfigure.properties.PropertyMapping;
28-
import org.springframework.boot.test.webservices.client.MockWebServiceServers;
2928
import org.springframework.ws.test.client.MockWebServiceServer;
3029

3130
/**
@@ -44,7 +43,7 @@
4443
public @interface AutoConfigureMockWebServiceServer {
4544

4645
/**
47-
* If {@link MockWebServiceServers} bean should be registered. Defaults to
46+
* If {@link MockWebServiceServer} bean should be registered. Defaults to
4847
* {@code true}.
4948
* @return if mock support is enabled
5049
*/
Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,41 +16,34 @@
1616

1717
package org.springframework.boot.test.autoconfigure.webservices.client;
1818

19-
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
2019
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2120
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
22-
import org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration;
23-
import org.springframework.boot.test.webservices.client.DefaultMockWebServiceServers;
24-
import org.springframework.boot.test.webservices.client.MockWebServiceServerRegistry;
25-
import org.springframework.boot.test.webservices.client.MockWebServiceServers;
26-
import org.springframework.boot.webservices.client.WebServiceTemplateCustomizer;
2721
import org.springframework.context.annotation.Bean;
2822
import org.springframework.context.annotation.Configuration;
2923
import org.springframework.ws.client.core.WebServiceTemplate;
3024
import org.springframework.ws.test.client.MockWebServiceServer;
3125

3226
/**
33-
* Auto-configuration for {@link MockWebServiceServers} support.
27+
* Auto-configuration for {@link MockWebServiceServer} support.
3428
*
3529
* @author Dmytro Nosan
3630
* @see AutoConfigureMockWebServiceServer
3731
* @since 2.2.0
3832
*/
3933
@Configuration(proxyBeanMethods = false)
4034
@ConditionalOnProperty(prefix = "spring.test.webservice.client.mock-server", name = "enabled")
41-
@AutoConfigureBefore(WebServiceTemplateAutoConfiguration.class)
4235
@ConditionalOnClass({ MockWebServiceServer.class, WebServiceTemplate.class })
43-
public class MockWebServiceServersAutoConfiguration {
36+
public class MockWebServiceServerAutoConfiguration {
4437

4538
@Bean
46-
public WebServiceTemplateCustomizer mockWebServiceServersWebServiceTemplateCustomizer(
47-
MockWebServiceServerRegistry registry) {
48-
return registry::bindTo;
39+
public MockWebServiceServer mockWebServiceServer() {
40+
return MockWebServiceServerUtils.createMockServer();
4941
}
5042

5143
@Bean
52-
public DefaultMockWebServiceServers mockWebServiceServers() {
53-
return new DefaultMockWebServiceServers();
44+
public MockWebServiceServerWebServiceTemplateCustomizer mockWebServiceServerWebServiceTemplateCustomizer(
45+
MockWebServiceServer mockWebServiceServer) {
46+
return new MockWebServiceServerWebServiceTemplateCustomizer(mockWebServiceServer);
5447
}
5548

5649
}
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,22 @@
1616

1717
package org.springframework.boot.test.autoconfigure.webservices.client;
1818

19-
import org.springframework.boot.test.webservices.client.MockWebServiceServers;
2019
import org.springframework.context.ApplicationContext;
2120
import org.springframework.core.Ordered;
2221
import org.springframework.test.context.TestContext;
2322
import org.springframework.test.context.TestExecutionListener;
2423
import org.springframework.test.context.support.AbstractTestExecutionListener;
2524
import org.springframework.util.ClassUtils;
25+
import org.springframework.ws.test.client.MockWebServiceServer;
2626

2727
/**
2828
* {@link TestExecutionListener} to {@code verify} and {@code reset}
29-
* {@link MockWebServiceServers}.
29+
* {@link MockWebServiceServer}.
3030
*
3131
* @author Dmytro Nosan
3232
* @since 2.2.0
3333
*/
34-
public class MockWebServiceServersTestExecutionListener extends AbstractTestExecutionListener {
34+
public class MockWebServiceServerTestExecutionListener extends AbstractTestExecutionListener {
3535

3636
private static final String MOCK_SERVER_CLASS = "org.springframework.ws.test.client.MockWebServiceServer";
3737

@@ -44,11 +44,11 @@ public int getOrder() {
4444
public void afterTestMethod(TestContext testContext) {
4545
if (isMockWebServiceServerPresent()) {
4646
ApplicationContext applicationContext = testContext.getApplicationContext();
47-
String[] names = applicationContext.getBeanNamesForType(MockWebServiceServers.class, false, false);
47+
String[] names = applicationContext.getBeanNamesForType(MockWebServiceServer.class, false, false);
4848
for (String name : names) {
49-
MockWebServiceServers servers = applicationContext.getBean(name, MockWebServiceServers.class);
50-
servers.verifyAll();
51-
servers.resetAll();
49+
MockWebServiceServer mockServer = applicationContext.getBean(name, MockWebServiceServer.class);
50+
mockServer.verify();
51+
MockWebServiceServerUtils.reset(mockServer);
5252
}
5353
}
5454
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright 2012-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.autoconfigure.webservices.client;
18+
19+
import java.lang.reflect.Constructor;
20+
import java.lang.reflect.Field;
21+
import java.util.List;
22+
23+
import org.springframework.beans.BeanUtils;
24+
import org.springframework.util.Assert;
25+
import org.springframework.util.ClassUtils;
26+
import org.springframework.util.ReflectionUtils;
27+
import org.springframework.ws.test.client.MockWebServiceServer;
28+
import org.springframework.ws.transport.WebServiceMessageSender;
29+
30+
/**
31+
* Utility class for dealing with {@link MockWebServiceServer}.
32+
*
33+
* @author Dmytro Nosan
34+
*/
35+
abstract class MockWebServiceServerUtils {
36+
37+
/**
38+
* Reset the given mock server.
39+
* @param mockWebServiceServer the mock server
40+
*/
41+
static void reset(MockWebServiceServer mockWebServiceServer) {
42+
WebServiceMessageSender mockSender = getMockSender(mockWebServiceServer);
43+
List<?> connections = (List<?>) getField(mockSender, "expectedConnections");
44+
connections.clear();
45+
setField(mockSender, "connectionIterator", null);
46+
}
47+
48+
/**
49+
* Creates a deferred mock server.
50+
* @return the mock server
51+
*/
52+
static MockWebServiceServer createMockServer() {
53+
try {
54+
WebServiceMessageSender mockSender = createMockWebServiceMessageSender();
55+
return newInstance(MockWebServiceServer.class, new Class[] { mockSender.getClass() },
56+
new Object[] { mockSender });
57+
}
58+
catch (Exception ex) {
59+
throw new IllegalStateException(ex);
60+
}
61+
}
62+
63+
/**
64+
* Return the mock message sender from the given server.
65+
* @param mockWebServiceServer the mock server
66+
* @return the mock web sender
67+
*/
68+
static WebServiceMessageSender getMockSender(MockWebServiceServer mockWebServiceServer) {
69+
return (WebServiceMessageSender) getField(mockWebServiceServer, "mockMessageSender");
70+
}
71+
72+
private static WebServiceMessageSender createMockWebServiceMessageSender() throws Exception {
73+
Class<?> targetClass = ClassUtils.forName("org.springframework.ws.test.client.MockWebServiceMessageSender",
74+
MockWebServiceServerUtils.class.getClassLoader());
75+
return (WebServiceMessageSender) newInstance(targetClass, new Class[0], new Object[0]);
76+
}
77+
78+
private static <T> T newInstance(Class<? extends T> targetClass, Class<?>[] parameterTypes, Object[] arguments)
79+
throws Exception {
80+
Constructor<? extends T> constructor = ReflectionUtils.accessibleConstructor(targetClass, parameterTypes);
81+
return BeanUtils.instantiateClass(constructor, arguments);
82+
}
83+
84+
private static Object getField(Object target, String name) {
85+
Field field = ReflectionUtils.findField(target.getClass(), name);
86+
Assert.state(field != null, "Could not find a field [" + name + "] for [" + target + "]");
87+
ReflectionUtils.makeAccessible(field);
88+
return ReflectionUtils.getField(field, target);
89+
}
90+
91+
private static void setField(Object target, String name, Object value) {
92+
Field field = ReflectionUtils.findField(target.getClass(), name);
93+
Assert.state(field != null, "Could not find a field [" + name + "] for [" + target + "]");
94+
ReflectionUtils.makeAccessible(field);
95+
ReflectionUtils.setField(field, target, value);
96+
}
97+
98+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2012-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.autoconfigure.webservices.client;
18+
19+
import java.util.concurrent.atomic.AtomicBoolean;
20+
21+
import org.springframework.boot.webservices.client.WebServiceTemplateBuilder;
22+
import org.springframework.boot.webservices.client.WebServiceTemplateCustomizer;
23+
import org.springframework.ws.client.core.WebServiceTemplate;
24+
import org.springframework.ws.test.client.MockWebServiceServer;
25+
26+
/**
27+
* {@link WebServiceTemplateCustomizer} that can be applied to a
28+
* {@link WebServiceTemplateBuilder} instances to add {@link MockWebServiceServer}
29+
* support.
30+
*
31+
* @author Dmytro Nosan
32+
*/
33+
class MockWebServiceServerWebServiceTemplateCustomizer implements WebServiceTemplateCustomizer {
34+
35+
private final AtomicBoolean alreadyBounded = new AtomicBoolean();
36+
37+
private final MockWebServiceServer mockServer;
38+
39+
MockWebServiceServerWebServiceTemplateCustomizer(MockWebServiceServer mockServer) {
40+
this.mockServer = mockServer;
41+
}
42+
43+
@Override
44+
public void customize(WebServiceTemplate webServiceTemplate) {
45+
if (this.alreadyBounded.compareAndSet(false, true)) {
46+
webServiceTemplate.setMessageSender(MockWebServiceServerUtils.getMockSender(this.mockServer));
47+
}
48+
else {
49+
throw new IllegalStateException("@WebServiceClientTest supports only a single MockWebServiceServer");
50+
}
51+
}
52+
53+
}

spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/webservices/client/WebServiceClientTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,20 @@
3030
import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration;
3131
import org.springframework.boot.test.autoconfigure.core.AutoConfigureCache;
3232
import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters;
33-
import org.springframework.boot.test.webservices.client.MockWebServiceServers;
3433
import org.springframework.boot.webservices.client.WebServiceTemplateBuilder;
3534
import org.springframework.context.annotation.ComponentScan;
3635
import org.springframework.core.annotation.AliasFor;
3736
import org.springframework.core.env.Environment;
3837
import org.springframework.test.context.BootstrapWith;
3938
import org.springframework.test.context.junit.jupiter.SpringExtension;
4039
import org.springframework.ws.client.core.WebServiceTemplate;
40+
import org.springframework.ws.test.client.MockWebServiceServer;
4141

4242
/**
4343
* Annotation that can be used for a typical Spring web service client test. Can be used
4444
* when a test focuses <strong>only</strong> on beans that use
4545
* {@link WebServiceTemplateBuilder}. By default, tests annotated with
46-
* {@code WebServiceClientTest} will also auto-configure a {@link MockWebServiceServers}.
46+
* {@code WebServiceClientTest} will also auto-configure a {@link MockWebServiceServer}.
4747
* <p>
4848
* If you are testing a bean that doesn't use {@link WebServiceTemplateBuilder} but
4949
* instead injects a {@link WebServiceTemplate} directly, you can add

spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAuto
160160

161161
# AutoConfigureMockWebServiceServer
162162
org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureMockWebServiceServer=\
163-
org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServersAutoConfiguration
163+
org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerAutoConfiguration
164164

165165
# DefaultTestExecutionListenersPostProcessors
166166
org.springframework.boot.test.context.DefaultTestExecutionListenersPostProcessor=\
@@ -179,4 +179,4 @@ org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListen
179179
org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener,\
180180
org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener,\
181181
org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener,\
182-
org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServersTestExecutionListener
182+
org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener

spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/webservices/client/AnotherExampleWebServiceClient.java

Lines changed: 0 additions & 45 deletions
This file was deleted.

spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/webservices/client/AutoConfigureMockWebServiceServerEnabledIntegrationTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020

2121
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
2222
import org.springframework.beans.factory.annotation.Autowired;
23-
import org.springframework.boot.test.webservices.client.MockWebServiceServers;
2423
import org.springframework.context.ApplicationContext;
24+
import org.springframework.ws.test.client.MockWebServiceServer;
2525

2626
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
2727

@@ -41,7 +41,7 @@ class AutoConfigureMockWebServiceServerEnabledIntegrationTests {
4141
@Test
4242
void mockWebServiceServerShouldNotBeRegistered() {
4343
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
44-
.isThrownBy(() -> this.applicationContext.getBean(MockWebServiceServers.class));
44+
.isThrownBy(() -> this.applicationContext.getBean(MockWebServiceServer.class));
4545
}
4646

4747
}

spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/webservices/client/AutoConfigureWebServiceClientWebServiceTemplateIntegrationTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020

2121
import org.springframework.beans.factory.annotation.Autowired;
2222
import org.springframework.boot.test.context.SpringBootTest;
23-
import org.springframework.boot.test.webservices.client.MockWebServiceServers;
2423
import org.springframework.context.annotation.Configuration;
2524
import org.springframework.context.annotation.Import;
2625
import org.springframework.ws.client.core.WebServiceTemplate;
26+
import org.springframework.ws.test.client.MockWebServiceServer;
2727
import org.springframework.ws.test.client.RequestMatchers;
2828
import org.springframework.ws.test.client.ResponseCreators;
2929
import org.springframework.xml.transform.StringSource;
@@ -43,11 +43,11 @@ class AutoConfigureWebServiceClientWebServiceTemplateIntegrationTests {
4343
private WebServiceTemplate webServiceTemplate;
4444

4545
@Autowired
46-
private MockWebServiceServers servers;
46+
private MockWebServiceServer mockWebServiceServer;
4747

4848
@Test
4949
void webServiceTemplateTest() {
50-
this.servers.expect(RequestMatchers.payload(new StringSource("<request/>")))
50+
this.mockWebServiceServer.expect(RequestMatchers.payload(new StringSource("<request/>")))
5151
.andRespond(ResponseCreators.withPayload(new StringSource("<response/>")));
5252
this.webServiceTemplate.marshalSendAndReceive("https://example.com", new Request());
5353
}

0 commit comments

Comments
 (0)