Browse Source

Remove use of TestHttpClientAdapter

Now that HttpClientAdapter is deprecated and replaced by HttpExchangeAdapter
and ReactorHttpExchangeAdapter, our tests should use the new contracts.

See gh-30117
pull/30869/head
Rossen Stoyanchev 3 years ago committed by rstoyanchev
parent
commit
068dc7db28
  1. 5
      spring-web/src/test/java/org/springframework/web/service/invoker/CookieValueArgumentResolverTests.java
  2. 39
      spring-web/src/test/java/org/springframework/web/service/invoker/HttpClientServiceMethodTests.java
  3. 8
      spring-web/src/test/java/org/springframework/web/service/invoker/HttpExchangeAdapterServiceMethodTests.java
  4. 5
      spring-web/src/test/java/org/springframework/web/service/invoker/HttpMethodArgumentResolverTests.java
  5. 20
      spring-web/src/test/java/org/springframework/web/service/invoker/HttpServiceMethodTests.java
  6. 23
      spring-web/src/test/java/org/springframework/web/service/invoker/MultipartFileArgumentResolverTests.java
  7. 18
      spring-web/src/test/java/org/springframework/web/service/invoker/NamedValueArgumentResolverTests.java
  8. 5
      spring-web/src/test/java/org/springframework/web/service/invoker/PathVariableArgumentResolverTests.java
  9. 33
      spring-web/src/test/java/org/springframework/web/service/invoker/ReactiveHttpServiceMethodTests.java
  10. 8
      spring-web/src/test/java/org/springframework/web/service/invoker/ReactorExchangeAdapterHttpServiceMethodTests.java
  11. 5
      spring-web/src/test/java/org/springframework/web/service/invoker/RequestAttributeArgumentResolverTests.java
  12. 5
      spring-web/src/test/java/org/springframework/web/service/invoker/RequestBodyArgumentResolverTests.java
  13. 13
      spring-web/src/test/java/org/springframework/web/service/invoker/RequestHeaderArgumentResolverTests.java
  14. 5
      spring-web/src/test/java/org/springframework/web/service/invoker/RequestParamArgumentResolverTests.java
  15. 17
      spring-web/src/test/java/org/springframework/web/service/invoker/RequestPartArgumentResolverTests.java
  16. 37
      spring-web/src/test/java/org/springframework/web/service/invoker/TestAdapter.java
  17. 39
      spring-web/src/test/java/org/springframework/web/service/invoker/TestExchangeAdapter.java
  18. 126
      spring-web/src/test/java/org/springframework/web/service/invoker/TestHttpClientAdapter.java
  19. 97
      spring-web/src/test/java/org/springframework/web/service/invoker/TestReactorExchangeAdapter.java
  20. 13
      spring-web/src/test/java/org/springframework/web/service/invoker/UrlArgumentResolverTests.java
  21. 57
      spring-web/src/test/kotlin/org/springframework/web/service/invoker/HttpServiceMethodKotlinTests.kt
  22. 6
      spring-webflux/src/test/java/org/springframework/web/reactive/function/client/support/WebClientHttpServiceProxyTests.java

5
spring-web/src/test/java/org/springframework/web/service/invoker/CookieValueArgumentResolverTests.java

@ -35,9 +35,10 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -35,9 +35,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class CookieValueArgumentResolverTests {
private final TestHttpClientAdapter client = new TestHttpClientAdapter();
private final TestExchangeAdapter client = new TestExchangeAdapter();
private final Service service = HttpServiceProxyFactory.builder(this.client).build().createClient(Service.class);
private final Service service =
HttpServiceProxyFactory.builderFor(this.client).build().createClient(Service.class);
@Test

39
spring-web/src/test/java/org/springframework/web/service/invoker/HttpClientServiceMethodTests.java

@ -1,39 +0,0 @@ @@ -1,39 +0,0 @@
/*
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.service.invoker;
import org.junit.jupiter.api.BeforeEach;
/**
* Tests for {@link HttpServiceMethod} with a test {@link TestHttpClientAdapter} that
* stubs the client invocations.
* <p>
* The tests do not create or invoke {@code HttpServiceMethod} directly but rather use
* {@link HttpServiceProxyFactory} to create a service proxy in order to use a strongly
* typed interface without the need for class casts.
*
* @author Olga Maciaszek-Sharma
*/
public class HttpClientServiceMethodTests extends ReactiveHttpServiceMethodTests {
@BeforeEach
void setUp(){
this.client = new TestHttpClientAdapter();
this.proxyFactory = HttpServiceProxyFactory.builder((HttpClientAdapter) this.client).build();
}
}

8
spring-web/src/test/java/org/springframework/web/service/invoker/HttpExchangeAdapterServiceMethodTests.java

@ -19,7 +19,7 @@ package org.springframework.web.service.invoker; @@ -19,7 +19,7 @@ package org.springframework.web.service.invoker;
import org.junit.jupiter.api.BeforeEach;
/**
* Tests for {@link HttpServiceMethod} with a blocking test {@link TestHttpExchangeAdapter} that
* Tests for {@link HttpServiceMethod} with a blocking test {@link TestExchangeAdapter} that
* stubs the client invocations.
* <p>
* The tests do not create or invoke {@code HttpServiceMethod} directly but rather use
@ -32,10 +32,8 @@ class HttpExchangeAdapterServiceMethodTests extends HttpServiceMethodTests { @@ -32,10 +32,8 @@ class HttpExchangeAdapterServiceMethodTests extends HttpServiceMethodTests {
@BeforeEach
void setUp() {
this.client = new TestHttpExchangeAdapter();
this.proxyFactory = HttpServiceProxyFactory.builder()
.exchangeAdapter((HttpExchangeAdapter) this.client)
.build();
this.client = new TestExchangeAdapter();
this.proxyFactory = HttpServiceProxyFactory.builderFor(this.client).build();
}
}

5
spring-web/src/test/java/org/springframework/web/service/invoker/HttpMethodArgumentResolverTests.java

@ -35,9 +35,10 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException; @@ -35,9 +35,10 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
*/
class HttpMethodArgumentResolverTests {
private final TestHttpClientAdapter client = new TestHttpClientAdapter();
private final TestExchangeAdapter client = new TestExchangeAdapter();
private final Service service = HttpServiceProxyFactory.builder(this.client).build().createClient(Service.class);
private final Service service =
HttpServiceProxyFactory.builderFor(this.client).build().createClient(Service.class);
@Test

20
spring-web/src/test/java/org/springframework/web/service/invoker/HttpServiceMethodTests.java

@ -36,8 +36,8 @@ import static org.springframework.http.MediaType.APPLICATION_CBOR_VALUE; @@ -36,8 +36,8 @@ import static org.springframework.http.MediaType.APPLICATION_CBOR_VALUE;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
/**
* Base class for testing {@link HttpServiceMethod} with a test {@link TestHttpClientAdapter}
* and a test {@link TestHttpExchangeAdapter} that stub the client invocations.
* Base class for testing {@link HttpServiceMethod} with a test {@link TestExchangeAdapter}
* and a test {@link TestExchangeAdapter} that stub the client invocations.
*
* <p>
* The tests do not create or invoke {@code HttpServiceMethod} directly but rather use
@ -52,7 +52,7 @@ abstract class HttpServiceMethodTests { @@ -52,7 +52,7 @@ abstract class HttpServiceMethodTests {
protected static final ParameterizedTypeReference<String> BODY_TYPE = new ParameterizedTypeReference<>() {
};
protected TestAdapter client;
protected TestExchangeAdapter client;
protected HttpServiceProxyFactory proxyFactory;
@ -66,19 +66,19 @@ abstract class HttpServiceMethodTests { @@ -66,19 +66,19 @@ abstract class HttpServiceMethodTests {
assertThat(headers).isNotNull();
String body = service.getBody();
assertThat(body).isEqualTo(client.getInvokedMethodReference());
assertThat(body).isEqualTo(client.getInvokedMethodName());
Optional<String> optional = service.getBodyOptional();
assertThat(optional).contains("body");
assertThat(optional.get()).startsWith("exchangeForBody");
ResponseEntity<String> entity = service.getEntity();
assertThat(entity.getBody()).isEqualTo("entity");
assertThat(entity.getBody()).startsWith("exchangeForEntity");
ResponseEntity<Void> voidEntity = service.getVoidEntity();
assertThat(voidEntity.getBody()).isNull();
List<String> list = service.getList();
assertThat(list.get(0)).isEqualTo("body");
assertThat(list.get(0)).startsWith("exchangeForBody");
}
@Test
@ -104,10 +104,8 @@ abstract class HttpServiceMethodTests { @@ -104,10 +104,8 @@ abstract class HttpServiceMethodTests {
@Test
void typeAndMethodAnnotatedService() {
HttpExchangeAdapter actualClient = this.client instanceof HttpClientAdapter httpClient
? httpClient.asHttpExchangeAdapter() : (HttpExchangeAdapter) client;
HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder()
.exchangeAdapter(actualClient)
.exchangeAdapter(this.client)
.embeddedValueResolver(value -> (value.equals("${baseUrl}") ? "/base" : value))
.build();
@ -131,7 +129,7 @@ abstract class HttpServiceMethodTests { @@ -131,7 +129,7 @@ abstract class HttpServiceMethodTests {
}
protected void verifyClientInvocation(String methodName, @Nullable ParameterizedTypeReference<?> expectedBodyType) {
assertThat(this.client.getInvokedMethodReference()).isEqualTo(methodName);
assertThat(this.client.getInvokedMethodName()).isEqualTo(methodName);
assertThat(this.client.getBodyType()).isEqualTo(expectedBodyType);
}

23
spring-web/src/test/java/org/springframework/web/service/invoker/MultipartFileArgumentResolverTests.java

@ -18,7 +18,6 @@ package org.springframework.web.service.invoker; @@ -18,7 +18,6 @@ package org.springframework.web.service.invoker;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpEntity;
@ -42,16 +41,10 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -42,16 +41,10 @@ import static org.assertj.core.api.Assertions.assertThat;
@SuppressWarnings("unchecked")
class MultipartFileArgumentResolverTests {
private final TestHttpClientAdapter clientAdapter = new TestHttpClientAdapter();
private final TestExchangeAdapter client = new TestExchangeAdapter();
private TestClient client;
@BeforeEach
void setUp() {
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(this.clientAdapter).build();
this.client = factory.createClient(TestClient.class);
}
private final MultipartService multipartService =
HttpServiceProxyFactory.builderFor(this.client).build().createClient(MultipartService.class);
@Test
@ -60,8 +53,8 @@ class MultipartFileArgumentResolverTests { @@ -60,8 +53,8 @@ class MultipartFileArgumentResolverTests {
String originalFileName = "originalTestFileName";
MultipartFile testFile = new MockMultipartFile(fileName, originalFileName, "text/plain", "test".getBytes());
this.client.postMultipartFile(testFile);
Object value = this.clientAdapter.getRequestValues().getBodyValue();
this.multipartService.postMultipartFile(testFile);
Object value = this.client.getRequestValues().getBodyValue();
assertThat(value).isInstanceOf(MultiValueMap.class);
MultiValueMap<String, HttpEntity<?>> map = (MultiValueMap<String, HttpEntity<?>>) value;
@ -80,8 +73,8 @@ class MultipartFileArgumentResolverTests { @@ -80,8 +73,8 @@ class MultipartFileArgumentResolverTests {
@Test
void optionalMultipartFile() {
this.client.postOptionalMultipartFile(Optional.empty(), "anotherPart");
Object value = clientAdapter.getRequestValues().getBodyValue();
this.multipartService.postOptionalMultipartFile(Optional.empty(), "anotherPart");
Object value = client.getRequestValues().getBodyValue();
assertThat(value).isInstanceOf(MultiValueMap.class);
MultiValueMap<String, HttpEntity<?>> map = (MultiValueMap<String, HttpEntity<?>>) value;
@ -90,7 +83,7 @@ class MultipartFileArgumentResolverTests { @@ -90,7 +83,7 @@ class MultipartFileArgumentResolverTests {
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
private interface TestClient {
private interface MultipartService {
@PostExchange
void postMultipartFile(MultipartFile file);

18
spring-web/src/test/java/org/springframework/web/service/invoker/NamedValueArgumentResolverTests.java

@ -27,7 +27,6 @@ import java.util.Map; @@ -27,7 +27,6 @@ import java.util.Map;
import java.util.Optional;
import org.apache.groovy.util.Maps;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.core.MethodParameter;
@ -52,21 +51,14 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException @@ -52,21 +51,14 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
*/
class NamedValueArgumentResolverTests {
private final TestHttpClientAdapter client = new TestHttpClientAdapter();
private final TestExchangeAdapter client = new TestExchangeAdapter();
private final TestNamedValueArgumentResolver argumentResolver = new TestNamedValueArgumentResolver();
private Service service;
@BeforeEach
void setUp() throws Exception {
HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.client)
.customArgumentResolver(this.argumentResolver)
.build();
this.service = proxyFactory.createClient(Service.class);
}
private final Service service = HttpServiceProxyFactory.builderFor(this.client)
.customArgumentResolver(this.argumentResolver)
.build()
.createClient(Service.class);
@Test

5
spring-web/src/test/java/org/springframework/web/service/invoker/PathVariableArgumentResolverTests.java

@ -34,9 +34,10 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -34,9 +34,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class PathVariableArgumentResolverTests {
private final TestHttpClientAdapter client = new TestHttpClientAdapter();
private final TestExchangeAdapter client = new TestExchangeAdapter();
private final Service service = HttpServiceProxyFactory.builder(this.client).build().createClient(Service.class);
private final Service service =
HttpServiceProxyFactory.builderFor(this.client).build().createClient(Service.class);
@Test

33
spring-web/src/test/java/org/springframework/web/service/invoker/ReactiveHttpServiceMethodTests.java

@ -33,8 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -33,8 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* Base class for testing reactive scenarios in {@link HttpServiceMethod} with
* a test {@link TestHttpClientAdapter} and a test {@link TestHttpExchangeAdapter}
* that stub the client invocations.
* a test {@link TestReactorExchangeAdapter} that stub the client invocations.
*
* <p>
* The tests do not create or invoke {@code HttpServiceMethod} directly but rather use
@ -52,33 +51,33 @@ abstract class ReactiveHttpServiceMethodTests extends HttpServiceMethodTests { @@ -52,33 +51,33 @@ abstract class ReactiveHttpServiceMethodTests extends HttpServiceMethodTests {
Mono<Void> voidMono = service.execute();
StepVerifier.create(voidMono).verifyComplete();
verifyClientInvocation("void", null);
verifyClientInvocation("exchangeForMono", null);
Mono<HttpHeaders> headersMono = service.getHeaders();
StepVerifier.create(headersMono).expectNextCount(1).verifyComplete();
verifyClientInvocation("headers", null);
verifyClientInvocation("exchangeForHeadersMono", null);
Mono<String> body = service.getBody();
StepVerifier.create(body).expectNext("body").verifyComplete();
verifyClientInvocation("body", BODY_TYPE);
StepVerifier.create(body).expectNext("exchangeForBodyMono").verifyComplete();
verifyClientInvocation("exchangeForBodyMono", BODY_TYPE);
Flux<String> fluxBody = service.getFluxBody();
StepVerifier.create(fluxBody).expectNext("request", "To", "Body", "Flux").verifyComplete();
verifyClientInvocation("bodyFlux", BODY_TYPE);
StepVerifier.create(fluxBody).expectNext("exchange", "For", "Body", "Flux").verifyComplete();
verifyClientInvocation("exchangeForBodyFlux", BODY_TYPE);
Mono<ResponseEntity<Void>> voidEntity = service.getVoidEntity();
StepVerifier.create(voidEntity).expectNext(ResponseEntity.ok().build()).verifyComplete();
verifyClientInvocation("bodilessEntity", null);
verifyClientInvocation("exchangeForBodilessEntityMono", null);
Mono<ResponseEntity<String>> entity = service.getEntity();
StepVerifier.create(entity).expectNext(ResponseEntity.ok("requestToEntity"));
verifyClientInvocation("entity", BODY_TYPE);
StepVerifier.create(entity).expectNext(ResponseEntity.ok("exchangeForEntityMono"));
verifyClientInvocation("exchangeForEntityMono", BODY_TYPE);
Mono<ResponseEntity<Flux<String>>> fluxEntity = service.getFluxEntity();
StepVerifier.create(fluxEntity.flatMapMany(HttpEntity::getBody))
.expectNext("request", "To", "Entity", "Flux")
.expectNext("exchange", "For", "Entity", "Flux")
.verifyComplete();
verifyClientInvocation("entityFlux", BODY_TYPE);
verifyClientInvocation("exchangeForEntityFlux", BODY_TYPE);
assertThat(service.getDefaultMethodValue()).isEqualTo("default value");
}
@ -93,20 +92,20 @@ abstract class ReactiveHttpServiceMethodTests extends HttpServiceMethodTests { @@ -93,20 +92,20 @@ abstract class ReactiveHttpServiceMethodTests extends HttpServiceMethodTests {
assertThat(headersSingle.blockingGet()).isNotNull();
Single<String> bodySingle = service.getBody();
assertThat(bodySingle.blockingGet()).isEqualTo("body");
assertThat(bodySingle.blockingGet()).isEqualTo("exchangeForBodyMono");
Flowable<String> bodyFlow = service.getFlowableBody();
assertThat(bodyFlow.toList().blockingGet()).asList().containsExactly("request", "To", "Body", "Flux");
assertThat(bodyFlow.toList().blockingGet()).asList().containsExactly("exchange", "For", "Body", "Flux");
Single<ResponseEntity<Void>> voidEntity = service.getVoidEntity();
assertThat(voidEntity.blockingGet().getBody()).isNull();
Single<ResponseEntity<String>> entitySingle = service.getEntity();
assertThat(entitySingle.blockingGet().getBody()).isEqualTo("entity");
assertThat(entitySingle.blockingGet().getBody()).isEqualTo("exchangeForEntityMono");
Single<ResponseEntity<Flowable<String>>> entityFlow = service.getFlowableEntity();
Flowable<String> body = (entityFlow.blockingGet()).getBody();
assertThat(body.toList().blockingGet()).containsExactly("request", "To", "Entity", "Flux");
assertThat(body.toList().blockingGet()).containsExactly("exchange", "For", "Entity", "Flux");
}
private interface ReactorService {

8
spring-web/src/test/java/org/springframework/web/service/invoker/ReactorExchangeAdapterHttpServiceMethodTests.java

@ -20,7 +20,7 @@ import org.junit.jupiter.api.BeforeEach; @@ -20,7 +20,7 @@ import org.junit.jupiter.api.BeforeEach;
/**
* Tests for {@link HttpServiceMethod} with an {@link HttpExchangeAdapter}
* build from a test {@link TestHttpClientAdapter} that stubs the client invocations.
* build from a test {@link TestReactorExchangeAdapter} that stubs the client invocations.
* <p>
* The tests do not create or invoke {@code HttpServiceMethod} directly but rather use
* {@link HttpServiceProxyFactory} to create a service proxy in order to use a strongly
@ -32,10 +32,8 @@ public class ReactorExchangeAdapterHttpServiceMethodTests extends ReactiveHttpSe @@ -32,10 +32,8 @@ public class ReactorExchangeAdapterHttpServiceMethodTests extends ReactiveHttpSe
@BeforeEach
void setUp() {
this.client = new TestHttpClientAdapter();
this.proxyFactory = HttpServiceProxyFactory.builder()
.exchangeAdapter(((HttpClientAdapter) this.client).asHttpExchangeAdapter())
.build();
this.client = new TestReactorExchangeAdapter();
this.proxyFactory = HttpServiceProxyFactory.builder().exchangeAdapter(this.client).build();
}
}

5
spring-web/src/test/java/org/springframework/web/service/invoker/RequestAttributeArgumentResolverTests.java

@ -32,9 +32,10 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -32,9 +32,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class RequestAttributeArgumentResolverTests {
private final TestHttpClientAdapter client = new TestHttpClientAdapter();
private final TestExchangeAdapter client = new TestExchangeAdapter();
private final Service service = HttpServiceProxyFactory.builder(this.client).build().createClient(Service.class);
private final Service service =
HttpServiceProxyFactory.builderFor(this.client).build().createClient(Service.class);
@Test

5
spring-web/src/test/java/org/springframework/web/service/invoker/RequestBodyArgumentResolverTests.java

@ -37,9 +37,10 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException; @@ -37,9 +37,10 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
*/
class RequestBodyArgumentResolverTests {
private final TestHttpClientAdapter client = new TestHttpClientAdapter();
private final TestExchangeAdapter client = new TestExchangeAdapter();
private final Service service = HttpServiceProxyFactory.builder(this.client).build().createClient(Service.class);
private final Service service =
HttpServiceProxyFactory.builderFor(this.client).build().createClient(Service.class);
@Test

13
spring-web/src/test/java/org/springframework/web/service/invoker/RequestHeaderArgumentResolverTests.java

@ -18,7 +18,6 @@ package org.springframework.web.service.invoker; @@ -18,7 +18,6 @@ package org.springframework.web.service.invoker;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.util.ObjectUtils;
@ -36,16 +35,10 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -36,16 +35,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class RequestHeaderArgumentResolverTests {
private final TestHttpClientAdapter client = new TestHttpClientAdapter();
private final TestExchangeAdapter client = new TestExchangeAdapter();
private Service service;
@BeforeEach
void setUp() throws Exception {
HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.client).build();
this.service = proxyFactory.createClient(Service.class);
}
private final Service service =
HttpServiceProxyFactory.builderFor(this.client).build().createClient(Service.class);
// Base class functionality should be tested in NamedValueArgumentResolverTests.

5
spring-web/src/test/java/org/springframework/web/service/invoker/RequestParamArgumentResolverTests.java

@ -39,9 +39,10 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -39,9 +39,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class RequestParamArgumentResolverTests {
private final TestHttpClientAdapter client = new TestHttpClientAdapter();
private final TestExchangeAdapter client = new TestExchangeAdapter();
private final Service service = HttpServiceProxyFactory.builder(this.client).build().createClient(Service.class);
private final Service service =
HttpServiceProxyFactory.builderFor(this.client).build().createClient(Service.class);
@Test

17
spring-web/src/test/java/org/springframework/web/service/invoker/RequestPartArgumentResolverTests.java

@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
package org.springframework.web.service.invoker;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
@ -41,16 +40,10 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -41,16 +40,10 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class RequestPartArgumentResolverTests {
private final TestHttpClientAdapter client = new TestHttpClientAdapter();
private final TestExchangeAdapter client = new TestExchangeAdapter();
private Service service;
@BeforeEach
void setUp() throws Exception {
HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.client).build();
this.service = proxyFactory.createClient(Service.class);
}
private final Service service =
HttpServiceProxyFactory.builderFor(this.client).build().createClient(Service.class);
// Base class functionality should be tested in NamedValueArgumentResolverTests.
@ -77,7 +70,9 @@ class RequestPartArgumentResolverTests { @@ -77,7 +70,9 @@ class RequestPartArgumentResolverTests {
private interface Service {
@PostExchange
void postMultipart(@RequestPart String part1, @RequestPart HttpEntity<String> part2, @RequestPart Mono<String> part3);
void postMultipart(
@RequestPart String part1, @RequestPart HttpEntity<String> part2,
@RequestPart Mono<String> part3);
}

37
spring-web/src/test/java/org/springframework/web/service/invoker/TestAdapter.java

@ -1,37 +0,0 @@ @@ -1,37 +0,0 @@
/*
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.service.invoker;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.lang.Nullable;
/**
* A helper interface for verifying method invoked on {@link HttpExchangeAdapter}
* and {@link HttpClientAdapter}, as well as their values.
*
* @author Olga Maciaszek-Sharma
*/
interface TestAdapter {
String getInvokedMethodReference();
HttpRequestValues getRequestValues();
@Nullable
ParameterizedTypeReference<?> getBodyType();
}

39
spring-web/src/test/java/org/springframework/web/service/invoker/TestHttpExchangeAdapter.java → spring-web/src/test/java/org/springframework/web/service/invoker/TestExchangeAdapter.java

@ -28,10 +28,10 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -28,10 +28,10 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* {@link HttpExchangeAdapter} with stubbed responses.
*
* @author Rossen Stoyanchev
* @author Olga Maciaszek-Sharma
*/
@SuppressWarnings("unchecked")
public class TestHttpExchangeAdapter implements HttpExchangeAdapter, TestAdapter {
public class TestExchangeAdapter implements HttpExchangeAdapter {
@Nullable
private String invokedMethodName;
@ -42,7 +42,8 @@ public class TestHttpExchangeAdapter implements HttpExchangeAdapter, TestAdapter @@ -42,7 +42,8 @@ public class TestHttpExchangeAdapter implements HttpExchangeAdapter, TestAdapter
@Nullable
private ParameterizedTypeReference<?> bodyType;
public String getInvokedMethodReference() {
public String getInvokedMethodName() {
assertThat(this.invokedMethodName).isNotNull();
return this.invokedMethodName;
}
@ -52,7 +53,6 @@ public class TestHttpExchangeAdapter implements HttpExchangeAdapter, TestAdapter @@ -52,7 +53,6 @@ public class TestHttpExchangeAdapter implements HttpExchangeAdapter, TestAdapter
return this.requestValues;
}
@Override
@Nullable
public ParameterizedTypeReference<?> getBodyType() {
return this.bodyType;
@ -60,45 +60,48 @@ public class TestHttpExchangeAdapter implements HttpExchangeAdapter, TestAdapter @@ -60,45 +60,48 @@ public class TestHttpExchangeAdapter implements HttpExchangeAdapter, TestAdapter
@Override
public void exchange(HttpRequestValues requestValues) {
saveInput("void", requestValues, null);
saveInput("exchange", requestValues, null);
}
@Override
public HttpHeaders exchangeForHeaders(HttpRequestValues requestValues) {
saveInput("headers", requestValues, null);
saveInput("exchangeForHeaders", requestValues, null);
return new HttpHeaders();
}
@SuppressWarnings("unchecked")
@Override
public <T> T exchangeForBody(HttpRequestValues requestValues, ParameterizedTypeReference<T> bodyType) {
saveInput("body", requestValues, bodyType);
return bodyType.getType().getTypeName().contains("List")
? (T) Collections.singletonList(getInvokedMethodReference()) : (T) getInvokedMethodReference();
saveInput("exchangeForBody", requestValues, bodyType);
return bodyType.getType().getTypeName().contains("List") ?
(T) Collections.singletonList(getInvokedMethodName()) : (T) getInvokedMethodName();
}
@Override
public ResponseEntity<Void> exchangeForBodilessEntity(HttpRequestValues requestValues) {
saveInput("bodilessEntity", requestValues, null);
saveInput("exchangeForBodilessEntity", requestValues, null);
return ResponseEntity.ok().build();
}
@SuppressWarnings("unchecked")
@Override
public <T> ResponseEntity<T> exchangeForEntity(HttpRequestValues requestValues,
ParameterizedTypeReference<T> bodyType) {
saveInput("entity", requestValues, bodyType);
return (ResponseEntity<T>) ResponseEntity.ok(this.getInvokedMethodReference());
public <T> ResponseEntity<T> exchangeForEntity(
HttpRequestValues requestValues, ParameterizedTypeReference<T> bodyType) {
saveInput("exchangeForEntity", requestValues, bodyType);
return (ResponseEntity<T>) ResponseEntity.ok(getInvokedMethodName());
}
@Override
public boolean supportsRequestAttributes() {
return false;
return true;
}
private <T> void saveInput(String methodName, HttpRequestValues requestValues,
@Nullable ParameterizedTypeReference<T> bodyType) {
protected <T> void saveInput(
String methodName, HttpRequestValues values, @Nullable ParameterizedTypeReference<T> bodyType) {
this.invokedMethodName = methodName;
this.requestValues = requestValues;
this.requestValues = values;
this.bodyType = bodyType;
}

126
spring-web/src/test/java/org/springframework/web/service/invoker/TestHttpClientAdapter.java

@ -1,126 +0,0 @@ @@ -1,126 +0,0 @@
/*
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.service.invoker;
import java.util.Collections;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.Nullable;
import static org.assertj.core.api.Assertions.assertThat;
/**
* {@link HttpClientAdapter} with stubbed responses.
*
* @author Rossen Stoyanchev
* @author Olga Maciaszek-Sharma
*/
@SuppressWarnings("unchecked")
class TestHttpClientAdapter implements HttpClientAdapter, TestAdapter {
@Nullable
private String invokedForReturnMethodReference;
@Nullable
private HttpRequestValues requestValues;
@Nullable
private ParameterizedTypeReference<?> bodyType;
@Override
public String getInvokedMethodReference() {
assertThat(this.invokedForReturnMethodReference).isNotNull();
return this.invokedForReturnMethodReference;
}
@Override
public HttpRequestValues getRequestValues() {
assertThat(this.requestValues).isNotNull();
return this.requestValues;
}
@Override
@Nullable
public ParameterizedTypeReference<?> getBodyType() {
return this.bodyType;
}
// HttpClientAdapter implementation
@Override
public Mono<Void> requestToVoid(HttpRequestValues requestValues) {
saveInput("void", requestValues, null);
return Mono.empty();
}
@Override
public Mono<HttpHeaders> requestToHeaders(HttpRequestValues requestValues) {
saveInput("headers", requestValues, null);
return Mono.just(new HttpHeaders());
}
@Override
public <T> Mono<T> requestToBody(HttpRequestValues requestValues, ParameterizedTypeReference<T> bodyType) {
saveInput("body", requestValues, bodyType);
return bodyType.getType().getTypeName().contains("List") ?
(Mono<T>) Mono.just(Collections.singletonList(getInvokedMethodReference()))
: (Mono<T>) Mono.just(getInvokedMethodReference());
}
@Override
public <T> Flux<T> requestToBodyFlux(HttpRequestValues requestValues, ParameterizedTypeReference<T> bodyType) {
saveInput("bodyFlux", requestValues, bodyType);
return (Flux<T>) Flux.just("request", "To", "Body", "Flux");
}
@Override
public Mono<ResponseEntity<Void>> requestToBodilessEntity(HttpRequestValues requestValues) {
saveInput("bodilessEntity", requestValues, null);
return Mono.just(ResponseEntity.ok().build());
}
@Override
public <T> Mono<ResponseEntity<T>> requestToEntity(
HttpRequestValues requestValues, ParameterizedTypeReference<T> type) {
saveInput("entity", requestValues, type);
return Mono.just((ResponseEntity<T>) ResponseEntity.ok("entity"));
}
@Override
public <T> Mono<ResponseEntity<Flux<T>>> requestToEntityFlux(
HttpRequestValues requestValues, ParameterizedTypeReference<T> bodyType) {
saveInput("entityFlux", requestValues, bodyType);
return Mono.just(ResponseEntity.ok((Flux<T>) Flux.just("request", "To", "Entity", "Flux")));
}
private <T> void saveInput(
String reference, HttpRequestValues requestValues, @Nullable ParameterizedTypeReference<T> bodyType) {
this.invokedForReturnMethodReference = reference;
this.requestValues = requestValues;
this.bodyType = bodyType;
}
}

97
spring-web/src/test/java/org/springframework/web/service/invoker/TestReactorExchangeAdapter.java

@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
/*
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.service.invoker;
import java.time.Duration;
import java.util.Collections;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
/**
* {@link ReactorHttpExchangeAdapter} with stubbed responses.
*
* @author Rossen Stoyanchev
* @author Olga Maciaszek-Sharma
*/
@SuppressWarnings("unchecked")
class TestReactorExchangeAdapter extends TestExchangeAdapter implements ReactorHttpExchangeAdapter {
@Override
public ReactiveAdapterRegistry getReactiveAdapterRegistry() {
return ReactiveAdapterRegistry.getSharedInstance();
}
@Override
public Duration getBlockTimeout() {
return Duration.ofSeconds(5);
}
@Override
public Mono<Void> exchangeForMono(HttpRequestValues requestValues) {
saveInput("exchangeForMono", requestValues, null);
return Mono.empty();
}
@Override
public Mono<HttpHeaders> exchangeForHeadersMono(HttpRequestValues requestValues) {
saveInput("exchangeForHeadersMono", requestValues, null);
return Mono.just(new HttpHeaders());
}
@Override
public <T> Mono<T> exchangeForBodyMono(HttpRequestValues requestValues, ParameterizedTypeReference<T> bodyType) {
saveInput("exchangeForBodyMono", requestValues, bodyType);
return bodyType.getType().getTypeName().contains("List") ?
(Mono<T>) Mono.just(Collections.singletonList(getInvokedMethodName())) :
(Mono<T>) Mono.just(getInvokedMethodName());
}
@Override
public <T> Flux<T> exchangeForBodyFlux(HttpRequestValues requestValues, ParameterizedTypeReference<T> bodyType) {
saveInput("exchangeForBodyFlux", requestValues, bodyType);
return (Flux<T>) Flux.just("exchange", "For", "Body", "Flux");
}
@Override
public Mono<ResponseEntity<Void>> exchangeForBodilessEntityMono(HttpRequestValues requestValues) {
saveInput("exchangeForBodilessEntityMono", requestValues, null);
return Mono.just(ResponseEntity.ok().build());
}
@Override
public <T> Mono<ResponseEntity<T>> exchangeForEntityMono(
HttpRequestValues requestValues, ParameterizedTypeReference<T> bodyType) {
saveInput("exchangeForEntityMono", requestValues, bodyType);
return Mono.just((ResponseEntity<T>) ResponseEntity.ok("exchangeForEntityMono"));
}
@Override
public <T> Mono<ResponseEntity<Flux<T>>> exchangeForEntityFlux(
HttpRequestValues requestValues, ParameterizedTypeReference<T> bodyType) {
saveInput("exchangeForEntityFlux", requestValues, bodyType);
return Mono.just(ResponseEntity.ok((Flux<T>) Flux.just("exchange", "For", "Entity", "Flux")));
}
}

13
spring-web/src/test/java/org/springframework/web/service/invoker/UrlArgumentResolverTests.java

@ -18,7 +18,6 @@ package org.springframework.web.service.invoker; @@ -18,7 +18,6 @@ package org.springframework.web.service.invoker;
import java.net.URI;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.lang.Nullable;
@ -34,16 +33,10 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException; @@ -34,16 +33,10 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
*/
class UrlArgumentResolverTests {
private final TestHttpClientAdapter client = new TestHttpClientAdapter();
private final TestExchangeAdapter client = new TestExchangeAdapter();
private Service service;
@BeforeEach
void setUp() throws Exception {
HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(this.client).build();
this.service = proxyFactory.createClient(Service.class);
}
private final Service service =
HttpServiceProxyFactory.builderFor(this.client).build().createClient(Service.class);
@Test

57
spring-web/src/test/kotlin/org/springframework/web/service/invoker/HttpServiceMethodKotlinTests.kt

@ -36,79 +36,78 @@ import org.springframework.web.service.annotation.GetExchange @@ -36,79 +36,78 @@ import org.springframework.web.service.annotation.GetExchange
@Suppress("DEPRECATION")
class KotlinHttpServiceMethodTests {
private val webClientAdapter = TestHttpClientAdapter()
private val httpExchangeAdapter = TestHttpExchangeAdapter()
private val proxyFactory = HttpServiceProxyFactory.builder(webClientAdapter).build()
private val blockingProxyFactory = HttpServiceProxyFactory.builder()
.exchangeAdapter(httpExchangeAdapter).build()
private val exchangeAdapter = TestExchangeAdapter()
private val reactorExchangeAdapter = TestReactorExchangeAdapter()
private val proxyFactory = HttpServiceProxyFactory.builderFor(this.exchangeAdapter).build()
private val reactorProxyFactory = HttpServiceProxyFactory.builderFor(this.reactorExchangeAdapter).build()
@Test
fun coroutinesService(): Unit = runBlocking {
val service = proxyFactory.createClient(FunctionsService::class.java)
val service = reactorProxyFactory.createClient(FunctionsService::class.java)
val stringBody = service.stringBody()
assertThat(stringBody).isEqualTo("body")
verifyClientInvocation("body", object : ParameterizedTypeReference<String>() {})
assertThat(stringBody).isEqualTo("exchangeForBodyMono")
verifyClientInvocation("exchangeForBodyMono", object : ParameterizedTypeReference<String>() {})
service.listBody()
verifyClientInvocation("body", object : ParameterizedTypeReference<MutableList<String>>() {})
verifyClientInvocation("exchangeForBodyMono", object : ParameterizedTypeReference<MutableList<String>>() {})
val flowBody = service.flowBody()
assertThat(flowBody.toList()).containsExactly("request", "To", "Body", "Flux")
verifyClientInvocation("bodyFlux", object : ParameterizedTypeReference<String>() {})
assertThat(flowBody.toList()).containsExactly("exchange", "For", "Body", "Flux")
verifyClientInvocation("exchangeForBodyFlux", object : ParameterizedTypeReference<String>() {})
val stringEntity = service.stringEntity()
assertThat(stringEntity).isEqualTo(ResponseEntity.ok<String>("entity"))
verifyClientInvocation("entity", object : ParameterizedTypeReference<String>() {})
assertThat(stringEntity).isEqualTo(ResponseEntity.ok<String>("exchangeForEntityMono"))
verifyClientInvocation("exchangeForEntityMono", object : ParameterizedTypeReference<String>() {})
service.listEntity()
verifyClientInvocation("entity", object : ParameterizedTypeReference<MutableList<String>>() {})
verifyClientInvocation("exchangeForEntityMono", object : ParameterizedTypeReference<MutableList<String>>() {})
val flowEntity = service.flowEntity()
assertThat(flowEntity.statusCode).isEqualTo(HttpStatus.OK)
assertThat(flowEntity.body!!.toList()).containsExactly("request", "To", "Entity", "Flux")
verifyClientInvocation("entityFlux", object : ParameterizedTypeReference<String>() {})
assertThat(flowEntity.body!!.toList()).containsExactly("exchange", "For", "Entity", "Flux")
verifyClientInvocation("exchangeForEntityFlux", object : ParameterizedTypeReference<String>() {})
}
@Test
fun blockingServiceWithExchangeResponseFunction() {
val service = blockingProxyFactory.createClient(BlockingFunctionsService::class.java)
val service = proxyFactory.createClient(BlockingFunctionsService::class.java)
val stringBody = service.stringBodyBlocking()
assertThat(stringBody).isEqualTo("body")
verifyTemplateInvocation("body", object : ParameterizedTypeReference<String>() {})
assertThat(stringBody).isEqualTo("exchangeForBody")
verifyTemplateInvocation("exchangeForBody", object : ParameterizedTypeReference<String>() {})
val listBody = service.listBodyBlocking()
assertThat(listBody.size).isEqualTo(1)
verifyTemplateInvocation("body", object : ParameterizedTypeReference<MutableList<String>>() {})
verifyTemplateInvocation("exchangeForBody", object : ParameterizedTypeReference<MutableList<String>>() {})
val stringEntity = service.stringEntityBlocking()
assertThat(stringEntity).isEqualTo(ResponseEntity.ok<String>("entity"))
verifyTemplateInvocation("entity", object : ParameterizedTypeReference<String>() {})
assertThat(stringEntity).isEqualTo(ResponseEntity.ok<String>("exchangeForEntity"))
verifyTemplateInvocation("exchangeForEntity", object : ParameterizedTypeReference<String>() {})
service.listEntityBlocking()
verifyTemplateInvocation("entity", object : ParameterizedTypeReference<MutableList<String>>() {})
verifyTemplateInvocation("exchangeForEntity", object : ParameterizedTypeReference<MutableList<String>>() {})
}
@Test
fun coroutineServiceWithExchangeResponseFunction() {
assertThatIllegalStateException().isThrownBy {
blockingProxyFactory.createClient(FunctionsService::class.java)
proxyFactory.createClient(FunctionsService::class.java)
}
assertThatIllegalStateException().isThrownBy {
blockingProxyFactory.createClient(SuspendingFunctionsService::class.java)
proxyFactory.createClient(SuspendingFunctionsService::class.java)
}
}
private fun verifyTemplateInvocation(methodReference: String, expectedBodyType: ParameterizedTypeReference<*>) {
assertThat(httpExchangeAdapter.invokedMethodReference).isEqualTo(methodReference)
assertThat(httpExchangeAdapter.bodyType).isEqualTo(expectedBodyType)
assertThat(exchangeAdapter.invokedMethodName).isEqualTo(methodReference)
assertThat(exchangeAdapter.bodyType).isEqualTo(expectedBodyType)
}
private fun verifyClientInvocation(methodReference: String, expectedBodyType: ParameterizedTypeReference<*>) {
assertThat(webClientAdapter.invokedMethodReference).isEqualTo(methodReference)
assertThat(webClientAdapter.bodyType).isEqualTo(expectedBodyType)
assertThat(reactorExchangeAdapter.invokedMethodName).isEqualTo(methodReference)
assertThat(reactorExchangeAdapter.bodyType).isEqualTo(expectedBodyType)
}
private interface FunctionsService : SuspendingFunctionsService {

6
spring-webflux/src/test/java/org/springframework/web/reactive/function/client/support/WebClientHttpServiceProxyTests.java

@ -163,10 +163,8 @@ public class WebClientHttpServiceProxyTests { @@ -163,10 +163,8 @@ public class WebClientHttpServiceProxyTests {
}
private TestHttpService initHttpService(WebClient webClient) {
return HttpServiceProxyFactory.builder()
.clientAdapter(WebClientAdapter.forClient(webClient))
.build()
.createClient(TestHttpService.class);
WebClientAdapter adapter = WebClientAdapter.forClient(webClient);
return HttpServiceProxyFactory.builderFor(adapter).build().createClient(TestHttpService.class);
}
private void prepareResponse(Consumer<MockResponse> consumer) {

Loading…
Cancel
Save