Description
Affects: Spring Boot 2.6.3 and below
During one of my integration tests, to test one endpoint I encountered the following error:
org.springframework.web.reactive.function.client.WebClientRequestException: Connection refused
I'm using the webflux starter version 2.6.3, but the problem I'm describing is reproducible with lower version.
These are the annotations applied to my test:
@SpringBootTest(webEnvironment = RANDOM_PORT)
@ActiveProfiles("test")
@Sql("classpath:sql/my_sql.sql")
@Import(TestConfig.class)
and this is the code is raising the issue:
URI uri = UriComponentsBuilder
.fromUriString(MY_URL)
.queryParam("year", 2005)
.buildAndExpand()
.toUri();
client.get()
.uri(uri)
.exchange()
.expectStatus()
.is2xxSuccessful();
After analyzing the problem, I found out that the issue is caused by the use of @SpringBootTest(webEnvironment = RANDOM_PORT)
without @AutoConfigureWebTestClient
(this should be possible since @SpringBootTest
registers a WebTestClient
) and the use of the S uri(URI uri);
implementation in the UriSpec
interface inside the WebTestClient
interface.
In other words by rewriting the test as:
URI uri = UriComponentsBuilder
.fromUriString(MY_URL)
.queryParam("year", 2005)
.buildAndExpand()
.toUri();
client.get()
.uri(uri.toString) // Using another method to specify the URI
.exchange()
.expectStatus()
.is2xxSuccessful();
The DefaultWebTestClient
is injected with a uriBuilderFactory
(DefaultUriBuilderFactory
) where its field private final UriComponentsBuilder baseUri;
is not null.
In the first case the URI returned is missing the base URI (http//host:port/
-- for example, /myUrl?year=2005
), whilst in the second case the URI returned contains the base URI (http//host:port/myUrl?year=2005
).
Another workaround is to put (a redundant) annotation:
@SpringBootTest(webEnvironment = RANDOM_PORT)
@ActiveProfiles("test")
@Sql(value = "classpath:sql/my_sql.sql")
@Import({TestConfig.class})
@AutoConfigureWebTestClient // the DefaultWebTestClient will be injected with different property values.
In this case the DefaultWebTestClient
is injected with private final UriComponentsBuilder baseUri;
equals to null, then the methods:
S uri(URI uri);
S uri(String uri, Object... uriVariables);
are consistent: both return the URI without the base URI, but in this case everything works.