我有一个@RestController
,它在其端点之一中使用WebClient
从同一控制器调用另一个端点:
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class FooRestController {
private final WebClient webClient;
@Value("${service.base-url}")
private String fooServiceBaseUrl;
@GetMapping(value = "/v1/foo", produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<Foo> getFoo() {
return webClient.get().uri(fooServiceBaseUrl + "/api/v1/fooAnother")
.retrieve()
.bodyToFlux(Foo.class);
}
@GetMapping(value = "/v1/fooAnother", produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<Foo> getFooAnother() {
return Flux.xxx
}
在我的@WebFluxTests
类中,我可以毫无问题地测试fooAnother
端点:
@ExtendWith(SpringExtension.class)
@Import({MyWebClientAutoConfiguration.class})
@WebFluxTest(FooRestController.class)
class FooRestControllerTest {
@Test
void shouldGetFooAnother() {
xxx
webTestClient.get()
.uri("/api/v1/fooAnother")
.exchange()
.expectStatus().isOk()
}
@Test
void shouldGetFoo() {
xxx
webTestClient.get()
.uri("/api/v1/fooAnother")
.exchange()
.expectStatus().isOk()
}
但是,当我测试/v1/foo
端点时(测试中的通知service.base-url
=“”),它无法调用具有webClient.get().uri(fooServiceBaseUrl + "/api/v1/fooAnother")
= fooServiceBaseUrl + "/api/v1/fooAnother"
的"/api/v1/fooAnother"
,并抱怨它需要一个绝对URL:java.lang.IllegalArgumentException: URI is not absolute: /api/v1/fooAnother
。
我该如何解决此测试?
WebClient
配置WebClient.Builder()
。您可以在FooRestController
内执行此操作,但是如果您还有其他WebClient自定义项,我想以这种方式使用Configuration
,则可以在不同的类中进行,而不是在控制器类中进行。配置WebClient:
@Configuration
public class WebClientConfig() {
@Value("${service.base-url}")
private String fooServiceBaseUrl;
@Bean
public WebClient webClient(WebClient.Builder builder) {
return builder
.baseUrl(fooServiceBaseUrl)
.build();
}
}
如果您决定继续在FooRestController
中配置webClient,则必须进行以下重构。您不需要上面的配置。如果这不能解决您的问题,则
application.yml
文件和您试图注入fooServiceBaseUrl
的值之间可能存在某种不匹配。
@RestController @RequestMapping("/api") public class FooRestController() { private final WebClient webClient; @Value("${service.base-url}") private String fooServiceBaseUrl; public FooRestController(WebClient.Builder webClientBuilder) { this.webClient = webClientBuilder .baseUrl(fooServiceBaseUrl) .build(); } .. .. }