在通过@WebFluxTests测试的控制器中使用WebClient会抛出java.lang.IllegalArgumentException:URI不是绝对的

问题描述 投票:0回答:1

我有一个@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

我该如何解决此测试?

spring spring-boot spring-webflux spring-test
1个回答
0
投票
您必须使用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(); } .. .. }

© www.soinside.com 2019 - 2024. All rights reserved.