Browse Source
Now that HttpClientAdapter is deprecated and replaced by HttpExchangeAdapter and ReactorHttpExchangeAdapter, our tests should use the new contracts. See gh-30117pull/30869/head
22 changed files with 222 additions and 362 deletions
@ -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(); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -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(); |
|
||||||
|
|
||||||
} |
|
||||||
@ -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; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -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"))); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue