Add @RestClientTest support
Add @RestClientTest annotation that can be used when testing REST clients. Provides auto-configuration for a MockRestServiceServer which can be used when the bean under test builds a single RestTemplate via the auto-configured RestTemplateBuilder. Closes gh-6030pull/6081/head
parent
b38231021d
commit
2eafb3d887
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.autoconfigure.properties.PropertyMapping;
|
||||||
|
import org.springframework.boot.test.web.client.MockServerRestTemplateCustomizer;
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation that can be applied to a test class to enable and configure
|
||||||
|
* auto-configuration of a single {@link MockRestServiceServer}. Only useful when a single
|
||||||
|
* call is made to {@link RestTemplateBuilder}. If multiple
|
||||||
|
* {@link org.springframework.web.client.RestTemplate RestTemplates} are in use, inject
|
||||||
|
* {@link MockServerRestTemplateCustomizer} and use
|
||||||
|
* {@link MockServerRestTemplateCustomizer#getServer(org.springframework.web.client.RestTemplate)
|
||||||
|
* getServer(RestTemplate)} or bind a {@link MockRestServiceServer} directly.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @since 1.4.0
|
||||||
|
* @see MockServerRestTemplateCustomizer
|
||||||
|
*/
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@ImportAutoConfiguration
|
||||||
|
@PropertyMapping("spring.test.webclient.mockrestserviceserver")
|
||||||
|
public @interface AutoConfigureMockRestServiceServer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If {@link MockServerRestTemplateCustomizer} should be enabled and
|
||||||
|
* {@link MockRestServiceServer} beans should be registered. Defaults to {@code true}
|
||||||
|
* @return if mock support is enabled
|
||||||
|
*/
|
||||||
|
boolean enabled() default true;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.autoconfigure.properties.PropertyMapping;
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation that can be applied to a test class to enable and configure
|
||||||
|
* auto-configuration of web clients.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @since 1.4.0
|
||||||
|
*/
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@ImportAutoConfiguration
|
||||||
|
@PropertyMapping("spring.test.webclient")
|
||||||
|
public @interface AutoConfigureWebClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a {@link RestTemplate} bean should be registered. Defaults to {@code false} with
|
||||||
|
* the assumption that the {@link RestTemplateBuilder} will be used.
|
||||||
|
* @return if a {@link RestTemplate} bean should be added.
|
||||||
|
*/
|
||||||
|
boolean registerRestTemplate() default false;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.test.web.client.MockServerRestTemplateCustomizer;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.client.ClientHttpRequest;
|
||||||
|
import org.springframework.http.client.ClientHttpResponse;
|
||||||
|
import org.springframework.test.web.client.ExpectedCount;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
|
import org.springframework.test.web.client.RequestExpectationManager;
|
||||||
|
import org.springframework.test.web.client.RequestMatcher;
|
||||||
|
import org.springframework.test.web.client.ResponseActions;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-configuration for {@link MockRestServiceServer} support.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @see AutoConfigureMockRestServiceServer
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnProperty(prefix = "spring.test.webclient.mockrestserviceserver", name = "enabled")
|
||||||
|
class MockRestServiceServerAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MockServerRestTemplateCustomizer mockServerRestTemplateCustomizer() {
|
||||||
|
return new MockServerRestTemplateCustomizer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MockRestServiceServer mockRestServiceServer(
|
||||||
|
MockServerRestTemplateCustomizer customizer) {
|
||||||
|
try {
|
||||||
|
return createDeferredMockRestServiceServer(customizer);
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new IllegalStateException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MockRestServiceServer createDeferredMockRestServiceServer(
|
||||||
|
MockServerRestTemplateCustomizer customizer) throws Exception {
|
||||||
|
Constructor<MockRestServiceServer> constructor = MockRestServiceServer.class
|
||||||
|
.getDeclaredConstructor(RequestExpectationManager.class);
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
return constructor.newInstance(new DeferredRequestExpectationManager(customizer));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link RequestExpectationManager} with the injected {@link MockRestServiceServer}
|
||||||
|
* so that the bean can be created before the
|
||||||
|
* {@link MockServerRestTemplateCustomizer#customize(RestTemplate)
|
||||||
|
* MockServerRestTemplateCustomizer} has been called.
|
||||||
|
*/
|
||||||
|
private static class DeferredRequestExpectationManager
|
||||||
|
implements RequestExpectationManager {
|
||||||
|
|
||||||
|
private MockServerRestTemplateCustomizer customizer;
|
||||||
|
|
||||||
|
DeferredRequestExpectationManager(MockServerRestTemplateCustomizer customizer) {
|
||||||
|
this.customizer = customizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseActions expectRequest(ExpectedCount count,
|
||||||
|
RequestMatcher requestMatcher) {
|
||||||
|
return getDelegate().expectRequest(count, requestMatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientHttpResponse validateRequest(ClientHttpRequest request)
|
||||||
|
throws IOException {
|
||||||
|
return getDelegate().validateRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void verify() {
|
||||||
|
getDelegate().verify();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
Map<RestTemplate, RequestExpectationManager> expectationManagers = this.customizer
|
||||||
|
.getExpectationManagers();
|
||||||
|
if (expectationManagers.size() == 1) {
|
||||||
|
getDelegate().reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RequestExpectationManager getDelegate() {
|
||||||
|
Map<RestTemplate, RequestExpectationManager> expectationManagers = this.customizer
|
||||||
|
.getExpectationManagers();
|
||||||
|
Assert.state(expectationManagers.size() > 0,
|
||||||
|
"Unable to use auto-configured MockRestServiceServer since "
|
||||||
|
+ "MockServerRestTemplateCustomizer has not been bound to "
|
||||||
|
+ "a RestTemplate");
|
||||||
|
Assert.state(expectationManagers.size() == 1,
|
||||||
|
"Unable to use auto-configured MockRestServiceServer since "
|
||||||
|
+ "MockServerRestTemplateCustomizer has been bound to "
|
||||||
|
+ "more than one RestTemplate");
|
||||||
|
return expectationManagers.values().iterator().next();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.test.context.TestContext;
|
||||||
|
import org.springframework.test.context.TestExecutionListener;
|
||||||
|
import org.springframework.test.context.support.AbstractTestExecutionListener;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link TestExecutionListener} to reset {@link MockRestServiceServer} beans.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
class MockRestServiceServerResetTestExecutionListener
|
||||||
|
extends AbstractTestExecutionListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTestMethod(TestContext testContext) throws Exception {
|
||||||
|
ApplicationContext applicationContext = testContext.getApplicationContext();
|
||||||
|
String[] names = applicationContext
|
||||||
|
.getBeanNamesForType(MockRestServiceServer.class, false, false);
|
||||||
|
for (String name : names) {
|
||||||
|
applicationContext.getBean(name, MockRestServiceServer.class).reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.Module;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.TypeExcludeFilter;
|
||||||
|
import org.springframework.boot.jackson.JsonComponent;
|
||||||
|
import org.springframework.boot.test.autoconfigure.filter.AnnotationCustomizableTypeExcludeFilter;
|
||||||
|
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||||
|
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||||
|
import org.springframework.core.type.classreading.MetadataReader;
|
||||||
|
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link TypeExcludeFilter} for {@link RestClientTest @RestClientTest}.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
|
class RestClientExcludeFilter extends AnnotationCustomizableTypeExcludeFilter {
|
||||||
|
|
||||||
|
private static final Set<Class<?>> DEFAULT_INCLUDES;
|
||||||
|
|
||||||
|
static {
|
||||||
|
Set<Class<?>> includes = new LinkedHashSet<Class<?>>();
|
||||||
|
includes.add(Module.class);
|
||||||
|
includes.add(JsonComponent.class);
|
||||||
|
DEFAULT_INCLUDES = Collections.unmodifiableSet(includes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final RestClientTest annotation;
|
||||||
|
|
||||||
|
RestClientExcludeFilter(Class<?> testClass) {
|
||||||
|
this.annotation = AnnotatedElementUtils.getMergedAnnotation(testClass,
|
||||||
|
RestClientTest.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean defaultInclude(MetadataReader metadataReader,
|
||||||
|
MetadataReaderFactory metadataReaderFactory) throws IOException {
|
||||||
|
if (super.defaultInclude(metadataReader, metadataReaderFactory)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (Class<?> controller : this.annotation.components()) {
|
||||||
|
if (isTypeOrAnnotated(metadataReader, metadataReaderFactory, controller)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean hasAnnotation() {
|
||||||
|
return this.annotation != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Filter[] getFilters(FilterType type) {
|
||||||
|
switch (type) {
|
||||||
|
case INCLUDE:
|
||||||
|
return this.annotation.includeFilters();
|
||||||
|
case EXCLUDE:
|
||||||
|
return this.annotation.excludeFilters();
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Unsupported type " + type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isUseDefaultFilters() {
|
||||||
|
return this.annotation.useDefaultFilters();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Set<Class<?>> getDefaultIncludes() {
|
||||||
|
return DEFAULT_INCLUDES;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.autoconfigure.core.AutoConfigureCache;
|
||||||
|
import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.core.annotation.AliasFor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.test.context.BootstrapWith;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation that can be used in combination with {@code @RunWith(SpringRunner.class)}
|
||||||
|
* for a typical Spring rest client test. Can be used when a test focuses
|
||||||
|
* <strong>only</strong> on beans that use {@link RestTemplateBuilder}.
|
||||||
|
* <p>
|
||||||
|
* Using this annotation will disable full auto-configuration and instead apply only
|
||||||
|
* configuration relevant to rest client tests (i.e. Jackson or GSON auto-configureation
|
||||||
|
* and {@code @JsonComponent} beans, but not regular {@link Component @Component} beans).
|
||||||
|
* <p>
|
||||||
|
* By default, tests annotated with {@code RestClientTest} will also auto-configure a
|
||||||
|
* {@link MockRestServiceServer}. For more fine-grained control the
|
||||||
|
* {@link AutoConfigureMockRestServiceServer @AutoConfigureMockRestServiceServer}
|
||||||
|
* annotation can be used.
|
||||||
|
* <p>
|
||||||
|
* If you are testing a bean that doesn't use {@link RestTemplateBuilder} but instead
|
||||||
|
* injects a {@link RestTemplate} directly, you can add
|
||||||
|
* {@code @AutoConfigureWebClient(registerRestTemplate=true)}.
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @since 1.4.0
|
||||||
|
*/
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
@BootstrapWith(SpringBootTestContextBootstrapper.class)
|
||||||
|
@OverrideAutoConfiguration(enabled = false)
|
||||||
|
@TypeExcludeFilters(RestClientExcludeFilter.class)
|
||||||
|
@AutoConfigureCache
|
||||||
|
@AutoConfigureWebClient
|
||||||
|
@AutoConfigureMockRestServiceServer
|
||||||
|
public @interface RestClientTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the components to test. This is an alias of {@link #components()} which
|
||||||
|
* can be used for brevity if no other attributes are defined. See
|
||||||
|
* {@link #components()} for details.
|
||||||
|
* @see #components()
|
||||||
|
* @return the components to test
|
||||||
|
*/
|
||||||
|
@AliasFor("components")
|
||||||
|
Class<?>[] value() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the components to test. May be left blank if components will be manually
|
||||||
|
* imported or created directly.
|
||||||
|
* @see #value()
|
||||||
|
* @return the components to test
|
||||||
|
*/
|
||||||
|
@AliasFor("value")
|
||||||
|
Class<?>[] components() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if default filtering should be used with
|
||||||
|
* {@link SpringBootApplication @SpringBootApplication}. By default only
|
||||||
|
* {@code @JsonComponent} and {@code Module} beans are included.
|
||||||
|
* @see #includeFilters()
|
||||||
|
* @see #excludeFilters()
|
||||||
|
* @return if default filters should be used
|
||||||
|
*/
|
||||||
|
boolean useDefaultFilters() default true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of include filters which can be used to add otherwise filtered beans to the
|
||||||
|
* application context.
|
||||||
|
* @return include filters to apply
|
||||||
|
*/
|
||||||
|
ComponentScan.Filter[] includeFilters() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of exclude filters which can be used to filter beans that would otherwise be
|
||||||
|
* added to the application context.
|
||||||
|
* @return exclude filters to apply
|
||||||
|
*/
|
||||||
|
ComponentScan.Filter[] excludeFilters() default {};
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration;
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-configuration for a web-client {@link RestTemplate}. Used when
|
||||||
|
* {@link AutoConfigureWebClient#registerRestTemplate()} is {@code true}.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @see AutoConfigureMockRestServiceServer
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnProperty(prefix = "spring.test.webclient", name = "register-rest-template")
|
||||||
|
@AutoConfigureAfter(WebClientAutoConfiguration.class)
|
||||||
|
class WebClientRestTemplateAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RestTemplate restTemplate(RestTemplateBuilder builder) {
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-configuration for web clients.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.test.autoconfigure.web.client;
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A second example web client used with {@link RestClientTest} tests.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class AnotherExampleRestClient {
|
||||||
|
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
public AnotherExampleRestClient(RestTemplateBuilder builder) {
|
||||||
|
this.restTemplate = builder.rootUri("http://example.com").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RestTemplate getRestTemplate() {
|
||||||
|
return this.restTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String test() {
|
||||||
|
return this.restTemplate.getForEntity("/test", String.class).getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.web.client.MockServerRestTemplateCustomizer;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link AutoConfigureMockRestServiceServer} with {@code enabled=false}.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@RestClientTest
|
||||||
|
@AutoConfigureMockRestServiceServer(enabled = false)
|
||||||
|
public class AutoConfigureMockRestServiceServerEnabledFalseIntegrationTests {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Test(expected = NoSuchBeanDefinitionException.class)
|
||||||
|
public void mockServerRestTemplateCustomizerShouldNotBeRegistered() throws Exception {
|
||||||
|
this.applicationContext.getBean(MockServerRestTemplateCustomizer.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
|
||||||
|
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link AutoConfigureWebClient} with {@code registerRestTemplate=true}.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest
|
||||||
|
@AutoConfigureWebClient(registerRestTemplate = true)
|
||||||
|
@AutoConfigureMockRestServiceServer
|
||||||
|
public class AutoConfigureWebClientWithRestTemplateIntegrationTests {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MockRestServiceServer server;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void restTemplateTest() throws Exception {
|
||||||
|
this.server.expect(requestTo("/test"))
|
||||||
|
.andRespond(withSuccess("hello", MediaType.TEXT_HTML));
|
||||||
|
ResponseEntity<String> entity = this.restTemplate.getForEntity("/test",
|
||||||
|
String.class);
|
||||||
|
assertThat(entity.getBody()).isEqualTo("hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
static class Config {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example web client used with {@link RestClientTest} tests.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class ExampleRestClient {
|
||||||
|
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
public ExampleRestClient(RestTemplateBuilder builder) {
|
||||||
|
this.restTemplate = builder.rootUri("http://example.com").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RestTemplate getRestTemplate() {
|
||||||
|
return this.restTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String test() {
|
||||||
|
return this.restTemplate.getForEntity("/test", String.class).getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example {@link SpringBootApplication} used with {@link RestClientTest} tests.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class ExampleWebClientApplication {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
|
||||||
|
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link RestClientTest} gets reset after test methods.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@RestClientTest(ExampleRestClient.class)
|
||||||
|
public class RestClientRestIntegrationTests {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MockRestServiceServer server;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ExampleRestClient client;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mockServerCall1() throws Exception {
|
||||||
|
this.server.expect(requestTo("/test"))
|
||||||
|
.andRespond(withSuccess("1", MediaType.TEXT_HTML));
|
||||||
|
assertThat(this.client.test()).isEqualTo("1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mockServerCall2() throws Exception {
|
||||||
|
this.server.expect(requestTo("/test"))
|
||||||
|
.andRespond(withSuccess("2", MediaType.TEXT_HTML));
|
||||||
|
assertThat(this.client.test()).isEqualTo("2");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
|
||||||
|
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link RestClientTest} with no specific client.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@RestClientTest
|
||||||
|
public class RestClientTestNoComponentIntegrationTests {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RestTemplateBuilder restTemplateBuilder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MockRestServiceServer server;
|
||||||
|
|
||||||
|
@Test(expected = NoSuchBeanDefinitionException.class)
|
||||||
|
public void exampleRestClientIsNotInjected() throws Exception {
|
||||||
|
this.applicationContext.getBean(ExampleRestClient.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void manuallyCreateBean() throws Exception {
|
||||||
|
ExampleRestClient client = new ExampleRestClient(this.restTemplateBuilder);
|
||||||
|
this.server.expect(requestTo("/test"))
|
||||||
|
.andRespond(withSuccess("hello", MediaType.TEXT_HTML));
|
||||||
|
assertThat(client.test()).isEqualTo("hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.web.client.MockServerRestTemplateCustomizer;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
|
||||||
|
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link RestClientTest} with two clients.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@RestClientTest({ ExampleRestClient.class, AnotherExampleRestClient.class })
|
||||||
|
public class RestClientTestTwoComponentsIntegrationTests {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ExampleRestClient client1;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AnotherExampleRestClient client2;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MockServerRestTemplateCustomizer customizer;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MockRestServiceServer server;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void serverShouldNotWork() throws Exception {
|
||||||
|
this.thrown.expect(IllegalStateException.class);
|
||||||
|
this.thrown.expectMessage("Unable to use auto-configured");
|
||||||
|
this.server.expect(requestTo("/test"))
|
||||||
|
.andRespond(withSuccess("hello", MediaType.TEXT_HTML));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void client1RestCallViaCustomizer() throws Exception {
|
||||||
|
this.customizer.getServer(this.client1.getRestTemplate())
|
||||||
|
.expect(requestTo("/test"))
|
||||||
|
.andRespond(withSuccess("hello", MediaType.TEXT_HTML));
|
||||||
|
assertThat(this.client1.test()).isEqualTo("hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void client2RestCallViaCustomizer() throws Exception {
|
||||||
|
this.customizer.getServer(this.client2.getRestTemplate())
|
||||||
|
.expect(requestTo("/test"))
|
||||||
|
.andRespond(withSuccess("there", MediaType.TEXT_HTML));
|
||||||
|
assertThat(this.client2.test()).isEqualTo("there");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.autoconfigure.web.client;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
|
||||||
|
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link RestClientTest} with a single client.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@RestClientTest(ExampleRestClient.class)
|
||||||
|
public class RestClientTestWithComponentIntegrationTests {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MockRestServiceServer server;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ExampleRestClient client;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mockServerCall() throws Exception {
|
||||||
|
this.server.expect(requestTo("/test"))
|
||||||
|
.andRespond(withSuccess("hello", MediaType.TEXT_HTML));
|
||||||
|
assertThat(this.client.test()).isEqualTo("hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.web.client;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.boot.web.client.RestTemplateCustomizer;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
|
import org.springframework.test.web.client.RequestExpectationManager;
|
||||||
|
import org.springframework.test.web.client.SimpleRequestExpectationManager;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link RestTemplateCustomizer} that can be applied to a {@link RestTemplateBuilder}
|
||||||
|
* instances to add {@link MockRestServiceServer} support.
|
||||||
|
* <p>
|
||||||
|
* Typically applied to an existing builder before it is used, for example:
|
||||||
|
* <pre class="code">
|
||||||
|
* MockServerRestTemplateCustomizer customizer = new MockServerRestTemplateCustomizer();
|
||||||
|
* MyBean bean = new MyBean(new RestTemplateBuilder(customizer));
|
||||||
|
* customizer.getServer().expect(requestTo("/hello")).andRespond(withSuccess());
|
||||||
|
* bean.makeRestCall();
|
||||||
|
* </pre>
|
||||||
|
* <p>
|
||||||
|
* If the customizer is only used once, the {@link #getServer()} method can be used to
|
||||||
|
* obtain the mock server. If the customizer has been used more than once the
|
||||||
|
* {@link #getServer(RestTemplate)} or {@link #getServers()} method must be used to access
|
||||||
|
* the related server.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @since 1.4.0
|
||||||
|
* @see #getServer()
|
||||||
|
* @see #getServer(RestTemplate)
|
||||||
|
*/
|
||||||
|
public class MockServerRestTemplateCustomizer implements RestTemplateCustomizer {
|
||||||
|
|
||||||
|
private Map<RestTemplate, RequestExpectationManager> expectationManagers = new ConcurrentHashMap<RestTemplate, RequestExpectationManager>();
|
||||||
|
|
||||||
|
private Map<RestTemplate, MockRestServiceServer> servers = new ConcurrentHashMap<RestTemplate, MockRestServiceServer>();
|
||||||
|
|
||||||
|
private final Class<? extends RequestExpectationManager> expectationManager;
|
||||||
|
|
||||||
|
private boolean detectRootUri = true;
|
||||||
|
|
||||||
|
public MockServerRestTemplateCustomizer() {
|
||||||
|
this.expectationManager = SimpleRequestExpectationManager.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MockServerRestTemplateCustomizer(
|
||||||
|
Class<? extends RequestExpectationManager> expectationManager) {
|
||||||
|
Assert.notNull(expectationManager, "ExpectationManager must not be null");
|
||||||
|
this.expectationManager = expectationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set if root URIs from {@link RootUriRequestExpectationManager} should be detected
|
||||||
|
* and applied to the {@link MockRestServiceServer}.
|
||||||
|
* @param detectRootUri if root URIs should be detected
|
||||||
|
*/
|
||||||
|
public void setDetectRootUri(boolean detectRootUri) {
|
||||||
|
this.detectRootUri = detectRootUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customize(RestTemplate restTemplate) {
|
||||||
|
RequestExpectationManager expectationManager = createExpecationManager();
|
||||||
|
if (this.detectRootUri) {
|
||||||
|
expectationManager = RootUriRequestExpectationManager
|
||||||
|
.forRestTemplate(restTemplate, expectationManager);
|
||||||
|
}
|
||||||
|
MockRestServiceServer server = MockRestServiceServer.bindTo(restTemplate)
|
||||||
|
.build(expectationManager);
|
||||||
|
this.expectationManagers.put(restTemplate, expectationManager);
|
||||||
|
this.servers.put(restTemplate, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RequestExpectationManager createExpecationManager() {
|
||||||
|
return BeanUtils.instantiate(this.expectationManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MockRestServiceServer getServer() {
|
||||||
|
Assert.state(this.servers.size() > 0,
|
||||||
|
"Unable to return a single MockRestServiceServer since "
|
||||||
|
+ "MockServerRestTemplateCustomizer has not been bound to "
|
||||||
|
+ "a RestTemplate");
|
||||||
|
Assert.state(this.servers.size() == 1,
|
||||||
|
"Unable to return a single MockRestServiceServer since "
|
||||||
|
+ "MockServerRestTemplateCustomizer has been bound to "
|
||||||
|
+ "more than one RestTemplate");
|
||||||
|
return this.servers.values().iterator().next();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<RestTemplate, RequestExpectationManager> getExpectationManagers() {
|
||||||
|
return this.expectationManagers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MockRestServiceServer getServer(RestTemplate restTemplate) {
|
||||||
|
return this.servers.get(restTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<RestTemplate, MockRestServiceServer> getServers() {
|
||||||
|
return Collections.unmodifiableMap(this.servers);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.web.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
import org.springframework.boot.web.client.RootUriTemplateHandler;
|
||||||
|
import org.springframework.http.client.ClientHttpRequest;
|
||||||
|
import org.springframework.http.client.ClientHttpResponse;
|
||||||
|
import org.springframework.http.client.support.HttpRequestWrapper;
|
||||||
|
import org.springframework.test.web.client.ExpectedCount;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer.MockRestServiceServerBuilder;
|
||||||
|
import org.springframework.test.web.client.RequestExpectationManager;
|
||||||
|
import org.springframework.test.web.client.RequestMatcher;
|
||||||
|
import org.springframework.test.web.client.ResponseActions;
|
||||||
|
import org.springframework.test.web.client.SimpleRequestExpectationManager;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import org.springframework.web.util.UriTemplateHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link RequestExpectationManager} that strips any the specified root URI from the
|
||||||
|
* request before verification. Can be used to simply test declarations when all REST
|
||||||
|
* calls start the same way. For example: <pre class="code">
|
||||||
|
* RestTemplate restTemplate = new RestTemplateBuilder().rootUri("http://example.com").build();
|
||||||
|
* MockRestServiceServer server = RootUriRequestExpectationManager.bindTo(restTemplate);
|
||||||
|
* server.expect(requestTo("/hello")).andRespond(withSuccess());
|
||||||
|
* restTemplate.getForEntity("/hello", String.class);
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @since 1.4.0
|
||||||
|
* @see RootUriTemplateHandler
|
||||||
|
* @see #bindTo(RestTemplate)
|
||||||
|
* @see #forRestTemplate(RestTemplate, RequestExpectationManager)
|
||||||
|
*/
|
||||||
|
public class RootUriRequestExpectationManager implements RequestExpectationManager {
|
||||||
|
|
||||||
|
private final String rootUri;
|
||||||
|
|
||||||
|
private final RequestExpectationManager expectationManager;
|
||||||
|
|
||||||
|
public RootUriRequestExpectationManager(String rootUri,
|
||||||
|
RequestExpectationManager expectationManager) {
|
||||||
|
Assert.notNull(rootUri, "RootUri must not be null");
|
||||||
|
Assert.notNull(expectationManager, "ExpectationManager must not be null");
|
||||||
|
this.rootUri = rootUri;
|
||||||
|
this.expectationManager = expectationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseActions expectRequest(ExpectedCount count,
|
||||||
|
RequestMatcher requestMatcher) {
|
||||||
|
return this.expectationManager.expectRequest(count, requestMatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientHttpResponse validateRequest(ClientHttpRequest request)
|
||||||
|
throws IOException {
|
||||||
|
String uri = request.getURI().toString();
|
||||||
|
if (uri.startsWith(this.rootUri)) {
|
||||||
|
uri = uri.substring(this.rootUri.length());
|
||||||
|
request = new ReplaceUriClientHttpRequest(uri, request);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return this.expectationManager.validateRequest(request);
|
||||||
|
}
|
||||||
|
catch (AssertionError ex) {
|
||||||
|
String message = ex.getMessage();
|
||||||
|
String prefix = "Request URI expected:</";
|
||||||
|
if (message != null && message.startsWith(prefix)) {
|
||||||
|
throw new AssertionError("Request URI expected:<" + this.rootUri
|
||||||
|
+ message.substring(prefix.length() - 1));
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void verify() {
|
||||||
|
this.expectationManager.verify();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
this.expectationManager.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a bound {@link MockRestServiceServer} for the given {@link RestTemplate},
|
||||||
|
* configured with {@link RootUriRequestExpectationManager} when possible.
|
||||||
|
* @param restTemplate the source reset template
|
||||||
|
* @return a configured {@link MockRestServiceServer}
|
||||||
|
*/
|
||||||
|
public static MockRestServiceServer bindTo(RestTemplate restTemplate) {
|
||||||
|
return bindTo(restTemplate, new SimpleRequestExpectationManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a bound {@link MockRestServiceServer} for the given {@link RestTemplate},
|
||||||
|
* configured with {@link RootUriRequestExpectationManager} when possible.
|
||||||
|
* @param restTemplate the source reset template
|
||||||
|
* @param expectationManager the source {@link RequestExpectationManager}
|
||||||
|
* @return a configured {@link MockRestServiceServer}
|
||||||
|
*/
|
||||||
|
public static MockRestServiceServer bindTo(RestTemplate restTemplate,
|
||||||
|
RequestExpectationManager expectationManager) {
|
||||||
|
MockRestServiceServerBuilder builder = MockRestServiceServer.bindTo(restTemplate);
|
||||||
|
return builder.build(forRestTemplate(restTemplate, expectationManager));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return {@link RequestExpectationManager} to be used for binding with the specified
|
||||||
|
* {@link RestTemplate}. If the {@link RestTemplate} is using a
|
||||||
|
* {@link RootUriTemplateHandler} then a {@link RootUriRequestExpectationManager} is
|
||||||
|
* returned, otherwise the source manager is returned unchanged.
|
||||||
|
* @param restTemplate the source reset template
|
||||||
|
* @param expectationManager the source {@link RequestExpectationManager}
|
||||||
|
* @return a {@link RequestExpectationManager} to be bound to the template
|
||||||
|
*/
|
||||||
|
public static RequestExpectationManager forRestTemplate(RestTemplate restTemplate,
|
||||||
|
RequestExpectationManager expectationManager) {
|
||||||
|
Assert.notNull(restTemplate, "RestTemplate must not be null");
|
||||||
|
UriTemplateHandler templateHandler = restTemplate.getUriTemplateHandler();
|
||||||
|
if (templateHandler instanceof RootUriTemplateHandler) {
|
||||||
|
return new RootUriRequestExpectationManager(
|
||||||
|
((RootUriTemplateHandler) templateHandler).getRootUri(),
|
||||||
|
expectationManager);
|
||||||
|
}
|
||||||
|
return expectationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ClientHttpRequest} wrapper to replace the request URI.
|
||||||
|
*/
|
||||||
|
private static class ReplaceUriClientHttpRequest extends HttpRequestWrapper
|
||||||
|
implements ClientHttpRequest {
|
||||||
|
|
||||||
|
private final URI uri;
|
||||||
|
|
||||||
|
ReplaceUriClientHttpRequest(String uri, ClientHttpRequest request) {
|
||||||
|
super(request);
|
||||||
|
try {
|
||||||
|
this.uri = new URI(uri);
|
||||||
|
}
|
||||||
|
catch (URISyntaxException ex) {
|
||||||
|
throw new IllegalStateException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URI getURI() {
|
||||||
|
return this.uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream getBody() throws IOException {
|
||||||
|
return getRequest().getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientHttpResponse execute() throws IOException {
|
||||||
|
return getRequest().execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientHttpRequest getRequest() {
|
||||||
|
return (ClientHttpRequest) super.getRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.web.client;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.test.web.client.RequestExpectationManager;
|
||||||
|
import org.springframework.test.web.client.SimpleRequestExpectationManager;
|
||||||
|
import org.springframework.test.web.client.UnorderedRequestExpectationManager;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
|
||||||
|
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link MockServerRestTemplateCustomizer}.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
public class MockServerRestTemplateCustomizerTests {
|
||||||
|
|
||||||
|
private MockServerRestTemplateCustomizer customizer;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
this.customizer = new MockServerRestTemplateCustomizer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createShouldUseSimpleRequestExpectationManager() throws Exception {
|
||||||
|
MockServerRestTemplateCustomizer customizer = new MockServerRestTemplateCustomizer();
|
||||||
|
customizer.customize(new RestTemplate());
|
||||||
|
assertThat(customizer.getServer()).extracting("expectationManager")
|
||||||
|
.hasAtLeastOneElementOfType(SimpleRequestExpectationManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createWhenExpectationManagerClassIsNullShouldThrowException()
|
||||||
|
throws Exception {
|
||||||
|
this.thrown.expect(IllegalArgumentException.class);
|
||||||
|
this.thrown.expectMessage("ExpectationManager must not be null");
|
||||||
|
new MockServerRestTemplateCustomizer(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createShouldUseExpectationMangerClass() throws Exception {
|
||||||
|
MockServerRestTemplateCustomizer customizer = new MockServerRestTemplateCustomizer(
|
||||||
|
UnorderedRequestExpectationManager.class);
|
||||||
|
customizer.customize(new RestTemplate());
|
||||||
|
assertThat(customizer.getServer()).extracting("expectationManager")
|
||||||
|
.hasAtLeastOneElementOfType(UnorderedRequestExpectationManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void detectRootUriShouldDefaultToTrue() throws Exception {
|
||||||
|
MockServerRestTemplateCustomizer customizer = new MockServerRestTemplateCustomizer(
|
||||||
|
UnorderedRequestExpectationManager.class);
|
||||||
|
customizer.customize(
|
||||||
|
new RestTemplateBuilder().rootUri("http://example.com").build());
|
||||||
|
assertThat(customizer.getServer()).extracting("expectationManager")
|
||||||
|
.hasAtLeastOneElementOfType(RootUriRequestExpectationManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setDetectRootUriShouldDisableRootUriDetection() throws Exception {
|
||||||
|
this.customizer.setDetectRootUri(false);
|
||||||
|
this.customizer.customize(
|
||||||
|
new RestTemplateBuilder().rootUri("http://example.com").build());
|
||||||
|
assertThat(this.customizer.getServer()).extracting("expectationManager")
|
||||||
|
.hasAtLeastOneElementOfType(SimpleRequestExpectationManager.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void customizeShouldBindServer() throws Exception {
|
||||||
|
RestTemplate template = new RestTemplateBuilder(this.customizer).build();
|
||||||
|
this.customizer.getServer().expect(requestTo("/test")).andRespond(withSuccess());
|
||||||
|
template.getForEntity("/test", String.class);
|
||||||
|
this.customizer.getServer().verify();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getServerWhenNoServersAreBoundShouldThrowException() throws Exception {
|
||||||
|
this.thrown.expect(IllegalStateException.class);
|
||||||
|
this.thrown.expectMessage("Unable to return a single MockRestServiceServer since "
|
||||||
|
+ "MockServerRestTemplateCustomizer has not been bound to a RestTemplate");
|
||||||
|
this.customizer.getServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getServerWhenMultipleServersAreBoundShouldThrowException()
|
||||||
|
throws Exception {
|
||||||
|
this.customizer.customize(new RestTemplate());
|
||||||
|
this.customizer.customize(new RestTemplate());
|
||||||
|
this.thrown.expect(IllegalStateException.class);
|
||||||
|
this.thrown.expectMessage("Unable to return a single MockRestServiceServer since "
|
||||||
|
+ "MockServerRestTemplateCustomizer has been bound to more than one RestTemplate");
|
||||||
|
this.customizer.getServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getServerWhenSingleServerIsBoundShouldReturnServer() throws Exception {
|
||||||
|
RestTemplate template = new RestTemplate();
|
||||||
|
this.customizer.customize(template);
|
||||||
|
assertThat(this.customizer.getServer())
|
||||||
|
.isEqualTo(this.customizer.getServer(template));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getServerWhenRestTemplateIsFoundShouldReturnServer() throws Exception {
|
||||||
|
RestTemplate template1 = new RestTemplate();
|
||||||
|
RestTemplate template2 = new RestTemplate();
|
||||||
|
this.customizer.customize(template1);
|
||||||
|
this.customizer.customize(template2);
|
||||||
|
assertThat(this.customizer.getServer(template1)).isNotNull();
|
||||||
|
assertThat(this.customizer.getServer(template2)).isNotNull()
|
||||||
|
.isNotSameAs(this.customizer.getServer(template1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getServerWhenRestTemplateIsNotFoundShouldReturnNull() throws Exception {
|
||||||
|
RestTemplate template1 = new RestTemplate();
|
||||||
|
RestTemplate template2 = new RestTemplate();
|
||||||
|
this.customizer.customize(template1);
|
||||||
|
assertThat(this.customizer.getServer(template1)).isNotNull();
|
||||||
|
assertThat(this.customizer.getServer(template2)).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getServersShouldReturnServers() throws Exception {
|
||||||
|
RestTemplate template1 = new RestTemplate();
|
||||||
|
RestTemplate template2 = new RestTemplate();
|
||||||
|
this.customizer.customize(template1);
|
||||||
|
this.customizer.customize(template2);
|
||||||
|
assertThat(this.customizer.getServers()).containsOnlyKeys(template1, template2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getExpectationManagersShouldReturnExpectationManagers() throws Exception {
|
||||||
|
RestTemplate template1 = new RestTemplate();
|
||||||
|
RestTemplate template2 = new RestTemplate();
|
||||||
|
this.customizer.customize(template1);
|
||||||
|
this.customizer.customize(template2);
|
||||||
|
RequestExpectationManager manager1 = this.customizer.getExpectationManagers()
|
||||||
|
.get(template1);
|
||||||
|
RequestExpectationManager manager2 = this.customizer.getExpectationManagers()
|
||||||
|
.get(template2);
|
||||||
|
assertThat(this.customizer.getServer(template1)).extracting("expectationManager")
|
||||||
|
.containsOnly(manager1);
|
||||||
|
assertThat(this.customizer.getServer(template2)).extracting("expectationManager")
|
||||||
|
.containsOnly(manager2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2016 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
|
||||||
|
*
|
||||||
|
* http://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.web.client;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||||
|
import org.springframework.http.client.ClientHttpRequest;
|
||||||
|
import org.springframework.http.client.support.HttpRequestWrapper;
|
||||||
|
import org.springframework.test.web.client.ExpectedCount;
|
||||||
|
import org.springframework.test.web.client.MockRestServiceServer;
|
||||||
|
import org.springframework.test.web.client.RequestExpectationManager;
|
||||||
|
import org.springframework.test.web.client.RequestMatcher;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
|
||||||
|
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link RootUriRequestExpectationManager}.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
public class RootUriRequestExpectationManagerTests {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
|
private String uri = "http://example.com";
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private RequestExpectationManager delegate;
|
||||||
|
|
||||||
|
private RootUriRequestExpectationManager manager;
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<ClientHttpRequest> requestCaptor;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
this.manager = new RootUriRequestExpectationManager(this.uri, this.delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createWhenRootUriIsNullShouldThrowException() throws Exception {
|
||||||
|
this.thrown.expect(IllegalArgumentException.class);
|
||||||
|
this.thrown.expectMessage("RootUri must not be null");
|
||||||
|
new RootUriRequestExpectationManager(null, this.delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createWhenExpectationManagerIsNullShouldThrowException()
|
||||||
|
throws Exception {
|
||||||
|
this.thrown.expect(IllegalArgumentException.class);
|
||||||
|
this.thrown.expectMessage("ExpectationManager must not be null");
|
||||||
|
new RootUriRequestExpectationManager(this.uri, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void expectRequestShouldDelegateToExpecationManager() throws Exception {
|
||||||
|
ExpectedCount count = mock(ExpectedCount.class);
|
||||||
|
RequestMatcher requestMatcher = mock(RequestMatcher.class);
|
||||||
|
this.manager.expectRequest(count, requestMatcher);
|
||||||
|
verify(this.delegate).expectRequest(count, requestMatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateRequestWhenUriDoesNotStartWithRootUriShouldDelegateToExpectationManager()
|
||||||
|
throws Exception {
|
||||||
|
ClientHttpRequest request = mock(ClientHttpRequest.class);
|
||||||
|
given(request.getURI()).willReturn(new URI("http://spring.io/test"));
|
||||||
|
this.manager.validateRequest(request);
|
||||||
|
verify(this.delegate).validateRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateRequestWhenUriStartsWithRootUriShouldReplaceUri()
|
||||||
|
throws Exception {
|
||||||
|
ClientHttpRequest request = mock(ClientHttpRequest.class);
|
||||||
|
given(request.getURI()).willReturn(new URI(this.uri + "/hello"));
|
||||||
|
this.manager.validateRequest(request);
|
||||||
|
verify(this.delegate).validateRequest(this.requestCaptor.capture());
|
||||||
|
HttpRequestWrapper actual = (HttpRequestWrapper) this.requestCaptor.getValue();
|
||||||
|
assertThat(actual.getRequest()).isSameAs(request);
|
||||||
|
assertThat(actual.getURI()).isEqualTo(new URI("/hello"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateRequestWhenRequestUriAssertionIsThrownShouldReplaceUriInMessage()
|
||||||
|
throws Exception {
|
||||||
|
ClientHttpRequest request = mock(ClientHttpRequest.class);
|
||||||
|
given(request.getURI()).willReturn(new URI(this.uri + "/hello"));
|
||||||
|
given(this.delegate.validateRequest((ClientHttpRequest) any()))
|
||||||
|
.willThrow(new AssertionError(
|
||||||
|
"Request URI expected:</hello> was:<http://example.com/bad>"));
|
||||||
|
this.thrown.expect(AssertionError.class);
|
||||||
|
this.thrown.expectMessage("Request URI expected:<http://example.com/hello>");
|
||||||
|
this.manager.validateRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resetRequestShouldDelegateToExpecationManager() throws Exception {
|
||||||
|
this.manager.reset();
|
||||||
|
verify(this.delegate).reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bindToShouldReturnMockResetServiceServer() throws Exception {
|
||||||
|
RestTemplate restTemplate = new RestTemplateBuilder().build();
|
||||||
|
MockRestServiceServer bound = RootUriRequestExpectationManager
|
||||||
|
.bindTo(restTemplate);
|
||||||
|
assertThat(bound).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bindToWithExpectationManagerShouldReturnMockResetServiceServer()
|
||||||
|
throws Exception {
|
||||||
|
RestTemplate restTemplate = new RestTemplateBuilder().build();
|
||||||
|
MockRestServiceServer bound = RootUriRequestExpectationManager
|
||||||
|
.bindTo(restTemplate, this.delegate);
|
||||||
|
assertThat(bound).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void forRestTemplateWhenUsingRootUriTemplateHandlerShouldReturnRootUriRequestExpectationManager()
|
||||||
|
throws Exception {
|
||||||
|
RestTemplate restTemplate = new RestTemplateBuilder().rootUri(this.uri).build();
|
||||||
|
RequestExpectationManager actual = RootUriRequestExpectationManager
|
||||||
|
.forRestTemplate(restTemplate, this.delegate);
|
||||||
|
assertThat(actual).isInstanceOf(RootUriRequestExpectationManager.class);
|
||||||
|
assertThat(actual).extracting("rootUri").containsExactly(this.uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void forRestTemplateWhenNotUsingRootUriTemplateHandlerShouldReturnOriginalUriRequestExpectationManager()
|
||||||
|
throws Exception {
|
||||||
|
RestTemplate restTemplate = new RestTemplateBuilder().build();
|
||||||
|
RequestExpectationManager actual = RootUriRequestExpectationManager
|
||||||
|
.forRestTemplate(restTemplate, this.delegate);
|
||||||
|
assertThat(actual).isSameAs(this.delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void boundRestTemplateShouldPrefixRootUri() {
|
||||||
|
RestTemplate restTemplate = new RestTemplateBuilder()
|
||||||
|
.rootUri("http://example.com").build();
|
||||||
|
MockRestServiceServer server = RootUriRequestExpectationManager
|
||||||
|
.bindTo(restTemplate);
|
||||||
|
server.expect(requestTo("/hello")).andRespond(withSuccess());
|
||||||
|
restTemplate.getForEntity("/hello", String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void boundRestTemplateWhenUrlIncludesDomainShouldNotPrefixRootUri() {
|
||||||
|
RestTemplate restTemplate = new RestTemplateBuilder()
|
||||||
|
.rootUri("http://example.com").build();
|
||||||
|
MockRestServiceServer server = RootUriRequestExpectationManager
|
||||||
|
.bindTo(restTemplate);
|
||||||
|
server.expect(requestTo("/hello")).andRespond(withSuccess());
|
||||||
|
this.thrown.expect(AssertionError.class);
|
||||||
|
this.thrown.expectMessage(
|
||||||
|
"expected:<http://example.com/hello> but was:<http://spring.io/hello>");
|
||||||
|
restTemplate.getForEntity("http://spring.io/hello", String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue