Description
Mikhail Konovalov opened SPR-15692 and commented
It seems that due to recursive generics in BodySpec
interface
interface BodySpec<B, S extends BodySpec<B, S>>
and due to expectBody
method returns
<B> BodySpec<B, ?> expectBody(Class<B> bodyType);
WebTestClient
cannot be used in Kotlin.
Kotlin inherits the result of .expectBody(Person::class.java)
as BodySpec<Person, *>
and thus the following methods in chain cannot be constructed due to the following error:
Error:(25, 20) Kotlin: Type inference failed: Not enough information to infer parameter T in fun <T : Nothing!> isEqualTo(p0: Controller.Person!): T!
Please specify it explicitly.
And it applies only Nothing
as a type parameter.
But in this case generated bytecode contains the following line
throw null
Example:
@Test
fun `test get`() {
val expectBody: BodySpec<Person, *> = client.get().uri("/person/42").exchange()
.expectBody(Person::class.java)
expectBody.isEqualTo(Person("42", "Ivan")) // doesn't compile here
expectBody.isEqualTo<BodySpec<Person, *>>(Person("42", "Ivan")) // doesn't compile here
expectBody.isEqualTo<Nothing>(Person("42", "Ivan")) // compile but lead to "throw null" in bytecode
}
If you work with list the situation is a bit better - Kotlin still cannot inherit type param automatically but you can specify it explicitly due to method expectBodyList
in interface ListBodySpec
doesn't return wildcards
<E> ListBodySpec<E> expectBodyList(Class<E> elementType);
Example:
@Test
fun `test list`() {
val expectBodyList: ListBodySpec<Person> = client.get().uri("/person").exchange()
.expectBodyList(Person::class.java)
expectBodyList.consumeWith<ListBodySpec<Person>> { list -> Assert.assertTrue(true) } // need to specify type param explicitly
}
Full example with java and kotlin can be found here.
Tests in java works well in these cases.
Affects: 5.0 RC2
Reference URL: https://gist.github.com/mskonovalov/42761bbc548e92c2af16c40cffcfcaf3
Issue Links:
- Unable to use WebTestClient with mock server in Kotlin #20606 Unable to use WebTestClient with mock server in Kotlin
Referenced from: commits 91c8b62, 568a0b5
0 votes, 5 watchers