Fix WebTestClient list assertions

Prior to this commit, the `WebTestClient` could only accept non-nullable
types in its `expectBodyList<T>` Kotlin extension function.
This commit relaxes this requirements to allow for more assertions.

Fixes gh-36476
This commit is contained in:
Brian Clozel
2026-03-16 11:14:55 +01:00
parent bc07a451dc
commit df817364b2
3 changed files with 12 additions and 3 deletions
@@ -900,13 +900,13 @@ public interface WebTestClient {
* List-specific assertions.
* @param elementType the expected List element type
*/
<E> ListBodySpec<E> expectBodyList(Class<E> elementType);
<E extends @Nullable Object> ListBodySpec<E> expectBodyList(Class<E> elementType);
/**
* Alternative to {@link #expectBodyList(Class)} that accepts information
* about a target type with generics.
*/
<E> ListBodySpec<E> expectBodyList(ParameterizedTypeReference<E> elementType);
<E extends @Nullable Object> ListBodySpec<E> expectBodyList(ParameterizedTypeReference<E> elementType);
/**
* Consume and decode the response body to {@code byte[]} and then apply
@@ -75,7 +75,7 @@ inline fun <reified B : Any> ResponseSpec.expectBody(): BodySpec<B, *> =
* @author Sebastien Deleuze
* @since 5.0
*/
inline fun <reified E : Any> ResponseSpec.expectBodyList(): ListBodySpec<E> =
inline fun <reified E : Any?> ResponseSpec.expectBodyList(): ListBodySpec<E> =
expectBodyList(object : ParameterizedTypeReference<E>() {})
/**
@@ -23,6 +23,7 @@ import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.reactivestreams.Publisher
import org.springframework.core.ParameterizedTypeReference
import org.springframework.http.MediaType
import org.springframework.web.reactive.function.server.router
import java.util.concurrent.CompletableFuture
@@ -95,6 +96,14 @@ class WebTestClientExtensionsTests {
verify { responseSpec.expectBodyList(object : ParameterizedTypeReference<Foo>() {}) }
}
@Test
fun `ResponseSpec#expectBodyList with null value`() {
WebTestClient
.bindToRouterFunction( router { GET("/") { ok().contentType(MediaType.APPLICATION_JSON).bodyValue("[null]") } } )
.build()
.get().uri("/").exchange().expectBodyList<Foo?>().hasSize(0)
}
@Test
fun `ResponseSpec#returnResult with reified type parameters`() {
responseSpec.returnResult<Foo>()