diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java index 4f16e60ecdf..9552f27c699 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * 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. @@ -26,6 +26,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Supplier; import org.apache.http.client.HttpClient; import org.apache.http.client.config.CookieSpecs; @@ -38,6 +39,9 @@ import org.apache.http.impl.client.HttpClients; import org.apache.http.protocol.HttpContext; import org.apache.http.ssl.SSLContextBuilder; +import org.springframework.beans.BeanInstantiationException; +import org.springframework.beans.BeanUtils; +import org.springframework.boot.web.client.ClientHttpRequestFactorySupplier; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.boot.web.client.RootUriTemplateHandler; import org.springframework.core.ParameterizedTypeReference; @@ -1023,7 +1027,8 @@ public class TestRestTemplate { /** * Creates a new {@code TestRestTemplate} with the same configuration as this one, * except that it will send basic authorization headers using the given - * {@code username} and {@code password}. + * {@code username} and {@code password}. The request factory used is a new instance + * of the underlying {@link RestTemplate}'s request factory type (when possible). * @param username the username * @param password the password * @return the new template @@ -1031,6 +1036,7 @@ public class TestRestTemplate { */ public TestRestTemplate withBasicAuth(String username, String password) { RestTemplate restTemplate = new RestTemplateBuilder() + .requestFactory(getRequestFactorySupplier()) .messageConverters(getRestTemplate().getMessageConverters()) .interceptors(getRestTemplate().getInterceptors()) .uriTemplateHandler(getRestTemplate().getUriTemplateHandler()).build(); @@ -1038,6 +1044,18 @@ public class TestRestTemplate { this.httpClientOptions); } + private Supplier getRequestFactorySupplier() { + return () -> { + try { + return BeanUtils + .instantiateClass(getRequestFactoryClass(getRestTemplate())); + } + catch (BeanInstantiationException ex) { + return new ClientHttpRequestFactorySupplier().get(); + } + }; + } + @SuppressWarnings({ "rawtypes", "unchecked" }) private RequestEntity createRequestEntityWithRootAppliedUri( RequestEntity requestEntity) { diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java index 65b84fb9961..5febcd016d2 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * 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. @@ -33,6 +33,7 @@ import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.RequestEntity; +import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; @@ -93,6 +94,35 @@ public class TestRestTemplateTests { .isInstanceOf(OkHttp3ClientHttpRequestFactory.class); } + @Test + public void useTheSameRequestFactoryClassWithBasicAuth() { + OkHttp3ClientHttpRequestFactory customFactory = new OkHttp3ClientHttpRequestFactory(); + RestTemplateBuilder builder = new RestTemplateBuilder() + .requestFactory(() -> customFactory); + TestRestTemplate testRestTemplate = new TestRestTemplate(builder) + .withBasicAuth("test", "test"); + RestTemplate restTemplate = testRestTemplate.getRestTemplate(); + Object requestFactory = ReflectionTestUtils + .getField(restTemplate.getRequestFactory(), "requestFactory"); + assertThat(requestFactory).isNotEqualTo(customFactory) + .hasSameClassAs(customFactory); + } + + @Test + public void withBasicAuthWhenRequestFactoryTypeCannotBeInstantiatedShouldFallback() { + TestClientHttpRequestFactory customFactory = new TestClientHttpRequestFactory( + "my-request-factory"); + RestTemplateBuilder builder = new RestTemplateBuilder() + .requestFactory(() -> customFactory); + TestRestTemplate testRestTemplate = new TestRestTemplate(builder) + .withBasicAuth("test", "test"); + RestTemplate restTemplate = testRestTemplate.getRestTemplate(); + Object requestFactory = ReflectionTestUtils + .getField(restTemplate.getRequestFactory(), "requestFactory"); + assertThat(requestFactory).isNotEqualTo(customFactory) + .isInstanceOf(CustomHttpComponentsClientHttpRequestFactory.class); + } + @Test public void getRootUriRootUriSetViaRestTemplateBuilder() { String rootUri = "http://example.com"; @@ -384,4 +414,17 @@ public class TestRestTemplateTests { } + static class TestClientHttpRequestFactory implements ClientHttpRequestFactory { + + TestClientHttpRequestFactory(String value) { + } + + @Override + public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) + throws IOException { + return null; + } + + } + }