Browse Source
This commit adds support for RestTestClient for MockMvc and integration tests. Closes gh-47335pull/47372/head
19 changed files with 854 additions and 7 deletions
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
/* |
||||
* Copyright 2012-present the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.docs.testing.springbootapplications.withrunningserver; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; |
||||
import org.springframework.test.web.servlet.client.RestTestClient; |
||||
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) |
||||
class MyRandomPortRestTestClientTests { |
||||
|
||||
@Test |
||||
void exampleTest(@Autowired RestTestClient webClient) { |
||||
// @formatter:off
|
||||
webClient |
||||
.get().uri("/") |
||||
.exchange() |
||||
.expectStatus().isOk() |
||||
.expectBody(String.class).isEqualTo("Hello World"); |
||||
// @formatter:on
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
/* |
||||
* Copyright 2012-present the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.web.server.test.client; |
||||
|
||||
import org.springframework.test.web.servlet.client.RestTestClient; |
||||
|
||||
/** |
||||
* A customizer that can be implemented by beans wishing to customize the |
||||
* {@link RestTestClient.Builder} to fine-tine its auto-configuration before a |
||||
* {@link RestTestClient} is created. |
||||
* |
||||
* @author Stephane Nicoll |
||||
* @since 4.0.0 |
||||
*/ |
||||
@FunctionalInterface |
||||
public interface RestTestClientBuilderCustomizer { |
||||
|
||||
/** |
||||
* Customize the given {@link RestTestClient.Builder Builder}. |
||||
* @param builder the builder |
||||
*/ |
||||
void customize(RestTestClient.Builder<?> builder); |
||||
|
||||
} |
||||
@ -0,0 +1,194 @@
@@ -0,0 +1,194 @@
|
||||
/* |
||||
* Copyright 2012-present the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.web.server.test.client; |
||||
|
||||
import org.jspecify.annotations.Nullable; |
||||
|
||||
import org.springframework.aot.AotDetector; |
||||
import org.springframework.beans.BeansException; |
||||
import org.springframework.beans.factory.BeanFactory; |
||||
import org.springframework.beans.factory.BeanFactoryAware; |
||||
import org.springframework.beans.factory.BeanFactoryUtils; |
||||
import org.springframework.beans.factory.FactoryBean; |
||||
import org.springframework.beans.factory.ListableBeanFactory; |
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException; |
||||
import org.springframework.beans.factory.config.BeanDefinition; |
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; |
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry; |
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; |
||||
import org.springframework.beans.factory.support.RootBeanDefinition; |
||||
import org.springframework.boot.restclient.RootUriBuilderFactory; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
import org.springframework.boot.web.server.reactive.AbstractReactiveWebServerFactory; |
||||
import org.springframework.context.ApplicationContext; |
||||
import org.springframework.context.ApplicationContextAware; |
||||
import org.springframework.context.ConfigurableApplicationContext; |
||||
import org.springframework.context.annotation.ConfigurationClassPostProcessor; |
||||
import org.springframework.core.Ordered; |
||||
import org.springframework.test.context.ContextCustomizer; |
||||
import org.springframework.test.context.MergedContextConfiguration; |
||||
import org.springframework.test.context.TestContextAnnotationUtils; |
||||
import org.springframework.test.web.servlet.client.RestTestClient; |
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* {@link ContextCustomizer} for {@link RestTestClient}. |
||||
* |
||||
* @author Stephane Nicoll |
||||
*/ |
||||
class RestTestClientContextCustomizer implements ContextCustomizer { |
||||
|
||||
@Override |
||||
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) { |
||||
if (AotDetector.useGeneratedArtifacts()) { |
||||
return; |
||||
} |
||||
SpringBootTest springBootTest = TestContextAnnotationUtils.findMergedAnnotation(mergedConfig.getTestClass(), |
||||
SpringBootTest.class); |
||||
Assert.state(springBootTest != null, "'springBootTest' must not be null"); |
||||
if (springBootTest.webEnvironment().isEmbedded()) { |
||||
registerRestTestClient(context); |
||||
} |
||||
} |
||||
|
||||
private void registerRestTestClient(ConfigurableApplicationContext context) { |
||||
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); |
||||
if (beanFactory instanceof BeanDefinitionRegistry registry) { |
||||
registerRestTestClient(registry); |
||||
} |
||||
} |
||||
|
||||
private void registerRestTestClient(BeanDefinitionRegistry registry) { |
||||
RootBeanDefinition definition = new RootBeanDefinition(RestTestClientRegistrar.class); |
||||
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); |
||||
registry.registerBeanDefinition(RestTestClientRegistrar.class.getName(), definition); |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(@Nullable Object obj) { |
||||
return (obj != null) && (obj.getClass() == getClass()); |
||||
} |
||||
|
||||
@Override |
||||
public int hashCode() { |
||||
return getClass().hashCode(); |
||||
} |
||||
|
||||
/** |
||||
* {@link BeanDefinitionRegistryPostProcessor} that runs after the |
||||
* {@link ConfigurationClassPostProcessor} and add a {@link RestTestClientFactory} |
||||
* bean definition when a {@link RestTestClient} hasn't already been registered. |
||||
*/ |
||||
static class RestTestClientRegistrar implements BeanDefinitionRegistryPostProcessor, Ordered, BeanFactoryAware { |
||||
|
||||
@SuppressWarnings("NullAway.Init") |
||||
private BeanFactory beanFactory; |
||||
|
||||
@Override |
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException { |
||||
this.beanFactory = beanFactory; |
||||
} |
||||
|
||||
@Override |
||||
public int getOrder() { |
||||
return Ordered.LOWEST_PRECEDENCE; |
||||
} |
||||
|
||||
@Override |
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { |
||||
if (AotDetector.useGeneratedArtifacts()) { |
||||
return; |
||||
} |
||||
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors((ListableBeanFactory) this.beanFactory, |
||||
RestTestClient.class, false, false).length == 0) { |
||||
registry.registerBeanDefinition(RestTestClient.class.getName(), |
||||
new RootBeanDefinition(RestTestClientFactory.class)); |
||||
} |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* {@link FactoryBean} used to create and configure a {@link RestTestClient}. |
||||
*/ |
||||
public static class RestTestClientFactory implements FactoryBean<RestTestClient>, ApplicationContextAware { |
||||
|
||||
@SuppressWarnings("NullAway.Init") |
||||
private ApplicationContext applicationContext; |
||||
|
||||
private @Nullable RestTestClient object; |
||||
|
||||
@Override |
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { |
||||
this.applicationContext = applicationContext; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isSingleton() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public Class<?> getObjectType() { |
||||
return RestTestClient.class; |
||||
} |
||||
|
||||
@Override |
||||
public RestTestClient getObject() { |
||||
if (this.object == null) { |
||||
this.object = createRestTestClient(); |
||||
} |
||||
return this.object; |
||||
} |
||||
|
||||
private RestTestClient createRestTestClient() { |
||||
boolean sslEnabled = isSslEnabled(this.applicationContext); |
||||
LocalHostUriTemplateHandler handler = new LocalHostUriTemplateHandler( |
||||
this.applicationContext.getEnvironment(), sslEnabled ? "https" : "http"); |
||||
RestTestClient.Builder<?> builder = RestTestClient.bindToServer(); |
||||
customizeRestTestClientBuilder(builder, this.applicationContext); |
||||
return builder.uriBuilderFactory(new RootUriBuilderFactory(handler.getRootUri(), handler)).build(); |
||||
} |
||||
|
||||
private boolean isSslEnabled(ApplicationContext context) { |
||||
try { |
||||
AbstractReactiveWebServerFactory webServerFactory = context |
||||
.getBean(AbstractReactiveWebServerFactory.class); |
||||
return webServerFactory.getSsl() != null && webServerFactory.getSsl().isEnabled(); |
||||
} |
||||
catch (NoSuchBeanDefinitionException ex) { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private void customizeRestTestClientBuilder(RestTestClient.Builder<?> clientBuilder, |
||||
ApplicationContext context) { |
||||
for (RestTestClientBuilderCustomizer customizer : context |
||||
.getBeansOfType(RestTestClientBuilderCustomizer.class) |
||||
.values()) { |
||||
customizer.customize(clientBuilder); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
/* |
||||
* Copyright 2012-present the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.web.server.test.client; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.jspecify.annotations.Nullable; |
||||
|
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
import org.springframework.test.context.ContextConfigurationAttributes; |
||||
import org.springframework.test.context.ContextCustomizer; |
||||
import org.springframework.test.context.ContextCustomizerFactory; |
||||
import org.springframework.test.context.TestContextAnnotationUtils; |
||||
import org.springframework.util.ClassUtils; |
||||
|
||||
/** |
||||
* {@link ContextCustomizerFactory} for {@code RestTestClient}. |
||||
* |
||||
* @author Stephane Nicoll |
||||
*/ |
||||
class RestTestClientContextCustomizerFactory implements ContextCustomizerFactory { |
||||
|
||||
private static final boolean restClientPresent; |
||||
|
||||
static { |
||||
ClassLoader loader = RestTestClientContextCustomizerFactory.class.getClassLoader(); |
||||
restClientPresent = ClassUtils.isPresent("org.springframework.web.client.RestClient", loader); |
||||
} |
||||
|
||||
@Override |
||||
public @Nullable ContextCustomizer createContextCustomizer(Class<?> testClass, |
||||
List<ContextConfigurationAttributes> configAttributes) { |
||||
SpringBootTest springBootTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, |
||||
SpringBootTest.class); |
||||
return (springBootTest != null && restClientPresent) ? new RestTestClientContextCustomizer() : null; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
/* |
||||
* Copyright 2012-present the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.web.server.test.client; |
||||
|
||||
import org.springframework.beans.factory.BeanFactory; |
||||
import org.springframework.beans.factory.BeanFactoryAware; |
||||
import org.springframework.beans.factory.BeanFactoryUtils; |
||||
import org.springframework.beans.factory.ListableBeanFactory; |
||||
import org.springframework.context.annotation.ImportSelector; |
||||
import org.springframework.core.type.AnnotationMetadata; |
||||
import org.springframework.test.web.servlet.client.RestTestClient; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* {@link ImportSelector} to check no {@link RestTestClient} definition is registered when |
||||
* config classes are processed. |
||||
*/ |
||||
class NoRestTestClientBeanChecker implements ImportSelector, BeanFactoryAware { |
||||
|
||||
@Override |
||||
public void setBeanFactory(BeanFactory beanFactory) { |
||||
assertThat(BeanFactoryUtils.beanNamesForTypeIncludingAncestors((ListableBeanFactory) beanFactory, |
||||
RestTestClient.class)) |
||||
.isEmpty(); |
||||
} |
||||
|
||||
@Override |
||||
public String[] selectImports(AnnotationMetadata importingClassMetadata) { |
||||
return new String[0]; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
|
||||
/* |
||||
* Copyright 2012-present the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.web.server.test.client; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.context.annotation.Import; |
||||
import org.springframework.test.annotation.DirtiesContext; |
||||
import org.springframework.test.web.servlet.client.RestTestClient; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import static org.mockito.ArgumentMatchers.any; |
||||
import static org.mockito.BDDMockito.then; |
||||
import static org.mockito.Mockito.mock; |
||||
|
||||
/** |
||||
* Integration test for {@link RestTestClientContextCustomizer}. |
||||
* |
||||
* @author Stephane Nicoll |
||||
*/ |
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) |
||||
@DirtiesContext |
||||
class RestTestClientContextCustomizerIntegrationTests { |
||||
|
||||
@Autowired |
||||
private RestTestClient webClient; |
||||
|
||||
@Autowired |
||||
private RestTestClientBuilderCustomizer clientBuilderCustomizer; |
||||
|
||||
@Test |
||||
void test() { |
||||
then(this.clientBuilderCustomizer).should().customize(any(RestTestClient.Builder.class)); |
||||
this.webClient.get().uri("/").exchange().expectBody(String.class).isEqualTo("hello"); |
||||
} |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
@Import({ TestWebMvcConfiguration.class, NoRestTestClientBeanChecker.class }) |
||||
@RestController |
||||
static class TestConfig { |
||||
|
||||
@GetMapping("/") |
||||
String root() { |
||||
return "hello"; |
||||
} |
||||
|
||||
@Bean |
||||
RestTestClientBuilderCustomizer clientBuilderCustomizer() { |
||||
return mock(RestTestClientBuilderCustomizer.class); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
/* |
||||
* Copyright 2012-present the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.web.server.test.client; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; |
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; |
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner; |
||||
import org.springframework.boot.web.server.test.client.RestTestClientContextCustomizer.RestTestClientRegistrar; |
||||
import org.springframework.context.ConfigurableApplicationContext; |
||||
import org.springframework.context.support.AbstractApplicationContext; |
||||
import org.springframework.test.context.MergedContextConfiguration; |
||||
import org.springframework.test.web.servlet.client.RestTestClient; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.mockito.BDDMockito.given; |
||||
import static org.mockito.Mockito.mock; |
||||
|
||||
/** |
||||
* Tests for {@link RestTestClientContextCustomizer}. |
||||
* |
||||
* @author Moritz Halbritter |
||||
*/ |
||||
class RestTestClientContextCustomizerTests { |
||||
|
||||
@Test |
||||
void whenContextIsNotABeanDefinitionRegistryRestTestClientIsRegistered() { |
||||
new ApplicationContextRunner(TestApplicationContext::new) |
||||
.withInitializer(this::applyRestTestClientContextCustomizer) |
||||
.run((context) -> assertThat(context).hasSingleBean(RestTestClient.class)); |
||||
} |
||||
|
||||
@Test |
||||
void whenUsingAotGeneratedArtifactsRestTestClientIsNotRegistered() { |
||||
new ApplicationContextRunner().withSystemProperties("spring.aot.enabled:true") |
||||
.withInitializer(this::applyRestTestClientContextCustomizer) |
||||
.run((context) -> { |
||||
assertThat(context).doesNotHaveBean(RestTestClientRegistrar.class); |
||||
assertThat(context).doesNotHaveBean(RestTestClient.class); |
||||
}); |
||||
} |
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" }) |
||||
void applyRestTestClientContextCustomizer(ConfigurableApplicationContext context) { |
||||
MergedContextConfiguration configuration = mock(MergedContextConfiguration.class); |
||||
given(configuration.getTestClass()).willReturn((Class) TestClass.class); |
||||
new RestTestClientContextCustomizer().customizeContext(context, configuration); |
||||
} |
||||
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) |
||||
static class TestClass { |
||||
|
||||
} |
||||
|
||||
static class TestApplicationContext extends AbstractApplicationContext { |
||||
|
||||
private final ConfigurableListableBeanFactory beanFactory = new DefaultListableBeanFactory(); |
||||
|
||||
@Override |
||||
protected void refreshBeanFactory() { |
||||
} |
||||
|
||||
@Override |
||||
protected void closeBeanFactory() { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public ConfigurableListableBeanFactory getBeanFactory() { |
||||
return this.beanFactory; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,88 @@
@@ -0,0 +1,88 @@
|
||||
/* |
||||
* Copyright 2012-present the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.web.server.test.client; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.beans.factory.annotation.Value; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; |
||||
import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; |
||||
import org.springframework.boot.web.server.servlet.ServletWebServerFactory; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.context.annotation.Import; |
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; |
||||
import org.springframework.test.context.TestPropertySource; |
||||
import org.springframework.test.web.servlet.client.RestTestClient; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
import org.springframework.web.servlet.DispatcherServlet; |
||||
|
||||
/** |
||||
* Integration test for {@link RestTestClientContextCustomizer} with a custom context |
||||
* path. |
||||
* |
||||
* @author Stephane Nicoll |
||||
*/ |
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) |
||||
@TestPropertySource(properties = "server.servlet.context-path=/test") |
||||
class RestTestClientContextCustomizerWithCustomContextPathIntegrationTests { |
||||
|
||||
@Autowired |
||||
private RestTestClient webClient; |
||||
|
||||
@Test |
||||
void test() { |
||||
this.webClient.get().uri("/").exchange().expectBody(String.class).isEqualTo("hello"); |
||||
} |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
@Import(NoRestTestClientBeanChecker.class) |
||||
@RestController |
||||
static class TestConfig { |
||||
|
||||
@Value("${server.port:8080}") |
||||
private int port = 8080; |
||||
|
||||
@Bean |
||||
DispatcherServlet dispatcherServlet() { |
||||
return new DispatcherServlet(); |
||||
} |
||||
|
||||
@Bean |
||||
ServletWebServerFactory webServerFactory() { |
||||
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); |
||||
factory.setPort(this.port); |
||||
factory.setContextPath("/test"); |
||||
return factory; |
||||
} |
||||
|
||||
@Bean |
||||
static PropertySourcesPlaceholderConfigurer propertyPlaceholder() { |
||||
return new PropertySourcesPlaceholderConfigurer(); |
||||
} |
||||
|
||||
@GetMapping("/") |
||||
String root() { |
||||
return "hello"; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,71 @@
@@ -0,0 +1,71 @@
|
||||
/* |
||||
* Copyright 2012-present the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.web.server.test.client; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.test.context.SpringBootTest; |
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.context.annotation.Import; |
||||
import org.springframework.test.web.servlet.client.RestTestClient; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.mockito.Mockito.mock; |
||||
|
||||
/** |
||||
* Integration test for {@link RestTestClientContextCustomizer} with a custom client. |
||||
* |
||||
* @author Stephane Nicoll |
||||
*/ |
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) |
||||
class RestTestClientContextCustomizerWithOverridePathIntegrationTests { |
||||
|
||||
@Autowired |
||||
private RestTestClient webClient; |
||||
|
||||
@Test |
||||
void test() { |
||||
assertThat(this.webClient).isInstanceOf(CustomRestTestClient.class); |
||||
} |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
@Import({ TestWebMvcConfiguration.class, NoRestTestClientBeanChecker.class }) |
||||
@RestController |
||||
static class TestConfig { |
||||
|
||||
@GetMapping("/") |
||||
String root() { |
||||
return "hello"; |
||||
} |
||||
|
||||
@Bean |
||||
CustomRestTestClient customRestTestClient() { |
||||
return mock(CustomRestTestClient.class); |
||||
} |
||||
|
||||
} |
||||
|
||||
interface CustomRestTestClient extends RestTestClient { |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
/* |
||||
* Copyright 2012-present the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.web.server.test.client; |
||||
|
||||
import org.springframework.beans.factory.annotation.Value; |
||||
import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; |
||||
import org.springframework.boot.web.server.servlet.ServletWebServerFactory; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; |
||||
import org.springframework.web.servlet.DispatcherServlet; |
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc; |
||||
|
||||
@Configuration(proxyBeanMethods = false) |
||||
@EnableWebMvc |
||||
class TestWebMvcConfiguration { |
||||
|
||||
@Value("${server.port:8080}") |
||||
private int port = 8080; |
||||
|
||||
@Bean |
||||
DispatcherServlet dispatcherServlet() { |
||||
return new DispatcherServlet(); |
||||
} |
||||
|
||||
@Bean |
||||
ServletWebServerFactory webServerFactory() { |
||||
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); |
||||
factory.setPort(this.port); |
||||
return factory; |
||||
} |
||||
|
||||
@Bean |
||||
static PropertySourcesPlaceholderConfigurer propertyPlaceholder() { |
||||
return new PropertySourcesPlaceholderConfigurer(); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue