diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebIntegrationTest.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebIntegrationTest.java index 2303e9d0cef..b04d9ba71ce 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebIntegrationTest.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebIntegrationTest.java @@ -23,10 +23,13 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.beans.factory.annotation.Autowire; import org.springframework.boot.test.context.IntegrationTest; import org.springframework.boot.test.context.SpringApplicationConfiguration; import org.springframework.boot.test.context.SpringApplicationContextLoader; import org.springframework.boot.test.context.SpringApplicationTest; +import org.springframework.boot.test.web.client.LocalHostUriTemplateHandler; +import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.context.ApplicationContext; import org.springframework.core.env.Environment; import org.springframework.test.context.BootstrapWith; @@ -49,6 +52,10 @@ import org.springframework.test.web.servlet.MockMvc; * application and want to mock the servlet environment (for example so that you can use * {@link MockMvc}) you should switch to the * {@link SpringApplicationTest @SpringApplicationTest} annotation. + *
+ * Tests that need to make REST calls to the started server can additionally
+ * {@link Autowire @Autowire} a {@link TestRestTemplate} which will be pre-configured with
+ * a {@link LocalHostUriTemplateHandler}.
*
* @author Phillip Webb
* @since 1.4.0
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebIntegrationTestContextCustomizer.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebIntegrationTestContextCustomizer.java
new file mode 100644
index 00000000000..035cc0774ed
--- /dev/null
+++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebIntegrationTestContextCustomizer.java
@@ -0,0 +1,61 @@
+/*
+ * 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.context.web;
+
+import org.springframework.boot.test.web.client.LocalHostUriTemplateHandler;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.env.Environment;
+import org.springframework.test.context.ContextCustomizer;
+import org.springframework.test.context.MergedContextConfiguration;
+
+/**
+ * {@link ContextCustomizer} for {@link WebIntegrationTest} that provides a
+ * {@link TestRestTemplate} bean that can automatically resolve
+ * {@literal local.server.port}.
+ *
+ * @author Phillip Webb
+ */
+class WebIntegrationTestContextCustomizer implements ContextCustomizer {
+
+ @Override
+ public void customizeContext(ConfigurableApplicationContext context,
+ MergedContextConfiguration mergedContextConfiguration) {
+ TestRestTemplate restTemplate = getRestTemplate(context.getEnvironment());
+ context.getBeanFactory().registerSingleton("testRestTemplate", restTemplate);
+ }
+
+ private TestRestTemplate getRestTemplate(Environment environment) {
+ TestRestTemplate template = new TestRestTemplate();
+ template.setUriTemplateHandler(new LocalHostUriTemplateHandler(environment));
+ return template;
+ }
+
+ @Override
+ public int hashCode() {
+ return getClass().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || obj.getClass() != getClass()) {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebIntegrationTestContextCustomizerFactory.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebIntegrationTestContextCustomizerFactory.java
new file mode 100644
index 00000000000..d731d8210c2
--- /dev/null
+++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebIntegrationTestContextCustomizerFactory.java
@@ -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.context.web;
+
+import java.util.List;
+
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.test.context.ContextConfigurationAttributes;
+import org.springframework.test.context.ContextCustomizer;
+import org.springframework.test.context.ContextCustomizerFactory;
+
+/**
+ * {@link ContextCustomizerFactory} for {@link WebIntegrationTest}.
+ *
+ * @author Phillip Webb
+ * @see WebIntegrationTestContextCustomizer
+ */
+class WebIntegrationTestContextCustomizerFactory implements ContextCustomizerFactory {
+
+ @Override
+ public ContextCustomizer createContextCustomizer(Class> testClass,
+ Listlocalhost:${local.server.port}.
+ *
+ * @author Phillip Webb
+ * @since 1.4.0
+ */
+public class LocalHostUriTemplateHandler extends DefaultUriTemplateHandler {
+
+ private final Environment environment;
+
+ public LocalHostUriTemplateHandler(Environment environment) {
+ Assert.notNull(environment, "Environment must not be null");
+ this.environment = environment;
+ }
+
+ @Override
+ public String getBaseUrl() {
+ String port = this.environment.getProperty("local.server.port", "8080");
+ return "http://localhost:" + port;
+ }
+
+}
diff --git a/spring-boot-test/src/main/resources/META-INF/spring.factories b/spring-boot-test/src/main/resources/META-INF/spring.factories
index 90927f93b90..50479f73419 100644
--- a/spring-boot-test/src/main/resources/META-INF/spring.factories
+++ b/spring-boot-test/src/main/resources/META-INF/spring.factories
@@ -1,6 +1,7 @@
# Spring Test ContextCustomizerFactories
org.springframework.test.context.ContextCustomizerFactory=\
org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizerFactory,\
+org.springframework.boot.test.context.web.WebIntegrationTestContextCustomizerFactory,\
org.springframework.boot.test.mock.mockito.MockitoContextCustomizerFactory
# Test Execution Listeners
diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/LocalHostUriTemplateHandlerTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/LocalHostUriTemplateHandlerTests.java
new file mode 100644
index 00000000000..c056cd4f414
--- /dev/null
+++ b/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/LocalHostUriTemplateHandlerTests.java
@@ -0,0 +1,61 @@
+/*
+ * 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.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import org.springframework.mock.env.MockEnvironment;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link LocalHostUriTemplateHandler}.
+ *
+ * @author Phillip Webb
+ */
+public class LocalHostUriTemplateHandlerTests {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void createWhenEnvironmentIsNullShouldThrowException() {
+ this.thrown.expect(IllegalArgumentException.class);
+ this.thrown.expectMessage("Environment must not be null");
+ new LocalHostUriTemplateHandler(null);
+ }
+
+ @Test
+ public void getBaseUrlShouldUseLocalServerPort() throws Exception {
+ MockEnvironment environment = new MockEnvironment();
+ environment.setProperty("local.server.port", "1234");
+ LocalHostUriTemplateHandler handler = new LocalHostUriTemplateHandler(
+ environment);
+ assertThat(handler.getBaseUrl()).isEqualTo("http://localhost:1234");
+ }
+
+ @Test
+ public void getBaseUrlWhenLocalServerPortMissingShouldUsePort8080() throws Exception {
+ MockEnvironment environment = new MockEnvironment();
+ LocalHostUriTemplateHandler handler = new LocalHostUriTemplateHandler(
+ environment);
+ assertThat(handler.getBaseUrl()).isEqualTo("http://localhost:8080");
+ }
+
+}