org.springframework.boot.test.context.SpringBootTestContextCustomizer Maven / Gradle / Ivy
/*
* Copyright 2012-2019 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.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.context.embedded.AbstractConfigurableEmbeddedServletContainer;
import org.springframework.boot.test.web.client.LocalHostUriTemplateHandler;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.client.TestRestTemplate.HttpClientOption;
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.test.context.ContextCustomizer;
import org.springframework.test.context.MergedContextConfiguration;
/**
* {@link ContextCustomizer} for {@link SpringBootTest}.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
class SpringBootTestContextCustomizer implements ContextCustomizer {
@Override
public void customizeContext(ConfigurableApplicationContext context,
MergedContextConfiguration mergedContextConfiguration) {
SpringBootTest annotation = AnnotatedElementUtils.getMergedAnnotation(mergedContextConfiguration.getTestClass(),
SpringBootTest.class);
if (annotation.webEnvironment().isEmbedded()) {
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.class.getName(),
new RootBeanDefinition(TestRestTemplateFactory.class));
}
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != getClass()) {
return false;
}
return true;
}
@Override
public int hashCode() {
return getClass().hashCode();
}
/**
* {@link FactoryBean} used to create and configure a {@link TestRestTemplate}.
*/
public static class TestRestTemplateFactory implements FactoryBean, ApplicationContextAware {
private static final HttpClientOption[] DEFAULT_OPTIONS = {};
private static final HttpClientOption[] SSL_OPTIONS = { HttpClientOption.SSL };
private TestRestTemplate object;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
RestTemplateBuilder builder = getRestTemplateBuilder(applicationContext);
boolean sslEnabled = isSslEnabled(applicationContext);
TestRestTemplate template = new TestRestTemplate(builder.build(), null, null,
sslEnabled ? SSL_OPTIONS : DEFAULT_OPTIONS);
LocalHostUriTemplateHandler handler = new LocalHostUriTemplateHandler(applicationContext.getEnvironment(),
sslEnabled ? "https" : "http");
template.setUriTemplateHandler(handler);
this.object = template;
}
private boolean isSslEnabled(ApplicationContext context) {
try {
AbstractConfigurableEmbeddedServletContainer container = context
.getBean(AbstractConfigurableEmbeddedServletContainer.class);
return container.getSsl() != null && container.getSsl().isEnabled();
}
catch (NoSuchBeanDefinitionException ex) {
return false;
}
}
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;
}
}
}