mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-08-29 03:06:45 +08:00
Configure TestRestTemplate using builder
Update SpringBootTestContextCustomizer to create the TestRestTemplate using the RestTemplateBuilder whenever possible. Fixes gh-5509
This commit is contained in:
parent
e1d74627f5
commit
433f5e7930
@ -16,11 +16,19 @@
|
||||
|
||||
package org.springframework.boot.test.context;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.boot.test.web.client.LocalHostUriTemplateHandler;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.test.context.ContextCustomizer;
|
||||
import org.springframework.test.context.MergedContextConfiguration;
|
||||
|
||||
@ -38,12 +46,24 @@ class SpringBootTestContextCustomizer implements ContextCustomizer {
|
||||
SpringBootTest annotation = AnnotatedElementUtils.getMergedAnnotation(
|
||||
mergedContextConfiguration.getTestClass(), SpringBootTest.class);
|
||||
if (annotation.webEnvironment().isEmbedded()) {
|
||||
Object restTemplate = TestRestTemplateFactory
|
||||
.createRestTemplate(context.getEnvironment());
|
||||
context.getBeanFactory().registerSingleton("testRestTemplate", restTemplate);
|
||||
registerTestRestTemplate(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerTestRestTemplate(ConfigurableApplicationContext context) {
|
||||
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
|
||||
if (beanFactory instanceof BeanDefinitionRegistry) {
|
||||
registerTestRestTemplate(context, (BeanDefinitionRegistry) context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void registerTestRestTemplate(ConfigurableApplicationContext context,
|
||||
BeanDefinitionRegistry registry) {
|
||||
registry.registerBeanDefinition("testRestTemplate",
|
||||
new RootBeanDefinition(TestRestTemplateFactory.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getClass().hashCode();
|
||||
@ -57,13 +77,47 @@ class SpringBootTestContextCustomizer implements ContextCustomizer {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Inner class to avoid references to web classes that may not be on the classpath
|
||||
private static class TestRestTemplateFactory {
|
||||
/**
|
||||
* {@link FactoryBean} used to create a configure a {@link TestRestTemplate}.
|
||||
*/
|
||||
public static class TestRestTemplateFactory
|
||||
implements FactoryBean<TestRestTemplate>, ApplicationContextAware {
|
||||
|
||||
private static TestRestTemplate createRestTemplate(Environment environment) {
|
||||
TestRestTemplate template = new TestRestTemplate();
|
||||
template.setUriTemplateHandler(new LocalHostUriTemplateHandler(environment));
|
||||
return template;
|
||||
private TestRestTemplate object;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
RestTemplateBuilder builder = getRestTemplateBuilder(applicationContext);
|
||||
TestRestTemplate template = new TestRestTemplate(builder.build());
|
||||
template.setUriTemplateHandler(
|
||||
new LocalHostUriTemplateHandler(applicationContext.getEnvironment()));
|
||||
this.object = template;
|
||||
}
|
||||
|
||||
private RestTemplateBuilder getRestTemplateBuilder(
|
||||
ApplicationContext applicationContext) {
|
||||
try {
|
||||
return applicationContext.getBean(RestTemplateBuilder.class);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
return new RestTemplateBuilder();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return TestRestTemplate.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestRestTemplate getObject() throws Exception {
|
||||
return this.object;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -91,30 +91,22 @@ public class TestRestTemplate {
|
||||
*/
|
||||
public TestRestTemplate(String username, String password,
|
||||
HttpClientOption... httpClientOptions) {
|
||||
this.restTemplate = createRestTemplate(username, password, httpClientOptions);
|
||||
this(new RestTemplate(), username, password, httpClientOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method used to create the underlying {@link RestTemplate}.
|
||||
* @param username the username to use (or {@code null})
|
||||
* @param password the password (or {@code null})
|
||||
* @param httpClientOptions client options to use if the Apache HTTP Client is used
|
||||
* @return the delegate {@link RestTemplate}
|
||||
*/
|
||||
protected RestTemplate createRestTemplate(String username, String password,
|
||||
public TestRestTemplate(RestTemplate restTemplate) {
|
||||
this(restTemplate, null, null);
|
||||
}
|
||||
|
||||
public TestRestTemplate(RestTemplate restTemplate, String username, String password,
|
||||
HttpClientOption... httpClientOptions) {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
Assert.notNull(restTemplate, "RestTemplate must not be null");
|
||||
if (ClassUtils.isPresent("org.apache.http.client.config.RequestConfig", null)) {
|
||||
restTemplate.setRequestFactory(
|
||||
new CustomHttpComponentsClientHttpRequestFactory(httpClientOptions));
|
||||
}
|
||||
addAuthentication(restTemplate, username, password);
|
||||
restTemplate.setErrorHandler(new NoOpResponseErrorHandler());
|
||||
return restTemplate;
|
||||
}
|
||||
|
||||
public TestRestTemplate(RestTemplate restTemplate) {
|
||||
Assert.notNull(restTemplate, "RestTemplate must not be null");
|
||||
this.restTemplate = restTemplate;
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,10 @@ public abstract class AbstractSpringBootTestEmbeddedWebEnvironmentTests {
|
||||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
public TestRestTemplate getRestTemplate() {
|
||||
return this.restTemplate;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runAndTestHttpEndpoint() {
|
||||
assertThat(this.port).isNotEqualTo(8080).isNotEqualTo(0);
|
||||
|
@ -16,15 +16,21 @@
|
||||
|
||||
package org.springframework.boot.test.context;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link SpringBootTest} configured with {@link WebEnvironment#RANDOM_PORT}.
|
||||
*
|
||||
@ -37,11 +43,28 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
public class SpringBootTestWebEnvironmentRandomPortTests
|
||||
extends AbstractSpringBootTestEmbeddedWebEnvironmentTests {
|
||||
|
||||
@Test
|
||||
public void testRestTemplateShouldUseBuilder() throws Exception {
|
||||
assertThat(getRestTemplate().getRestTemplate().getMessageConverters())
|
||||
.hasAtLeastOneElementOfType(MyConverter.class);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
@RestController
|
||||
protected static class Config extends AbstractConfig {
|
||||
|
||||
@Bean
|
||||
public RestTemplateBuilder restTemplateBuilder() {
|
||||
return new RestTemplateBuilder()
|
||||
.additionalMessageConverters(new MyConverter());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MyConverter extends StringHttpMessageConverter {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user