I'm setting up integration tests for a small Kotlin Spring Boot application. From what I have read, other people have had the same problems, but the suggested solutions do not work for me.
So, this is my test:
@Test
fun `Assert predefined checklists actually come back`(){
val assertedValues = listOf(
Checklist(listOf(Question("Wings"), Question("Whells"))),
Checklist(listOf(Question("Wings"), Question("Turbines"))))
val result = restTemplate
.withBasicAuth("username", "password")
.getForEntity<List<Checklist>>("/checklists")
assertThat(result.statusCode).isEqualTo(HttpStatus.OK)
assertThat(result.body).isNotNull
println(result.body)
for (checklist in result.body!!){
assertThat(assertedValues).contains(checklist)
}
}
As a recap, the problem surfacing here is that Jackson is unable to deserialize Kotlin's List class, so I get a ClassCastException:
java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class checklist.Checklist (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; checklist.Checklist is in unnamed module of loader 'app')
Neither Checklist
nor Question
are Kotlin data classes, just in case you want to ask.
What I found was this: Why kotlin jackson can't deserialize list
Bottom line: It may help to use Jackson's ObjectMapper in one of the following ways:
mapper.readValue(result, object : TypeReference<List<Checklist>>() {})
or, as in my case as I use the jackson-kotlin-module:
mapper.readValue<List<MyClass>>(result)
.
Sadly, this only leads to:
public final fun <T : Any!> readValue(p0: JsonParser!, p1: ResolvedType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: JsonParser!, p1: TypeReference<*>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: JsonParser!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: JsonParser!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: DataInput!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: DataInput!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: File!, p1: TypeReference<(raw) Any!>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: File!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: File!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: InputStream!, p1: TypeReference<(raw) Any!>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: InputStream!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: InputStream!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: Reader!, p1: TypeReference<(raw) Any!>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: Reader!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: Reader!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: URL!, p1: TypeReference<(raw) Any!>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: URL!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: URL!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: ByteArray!, p1: TypeReference<(raw) Any!>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: ByteArray!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: ByteArray!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: String!, p1: TypeReference<(raw) Any!>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: String!, p1: JavaType!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
public open fun <T : Any!> readValue(p0: String!, p1: Class<(???..???)>!): (???..???) defined in com.fasterxml.jackson.databind.ObjectMapper
or respectivley, in the latter case:
public inline fun <reified T> ObjectMapper.readValue(jp: JsonParser): List<Checklist> defined in com.fasterxml.jackson.module.kotlin
public inline fun <reified T> ObjectMapper.readValue(src: File): List<Checklist> defined in com.fasterxml.jackson.module.kotlin
public inline fun <reified T> ObjectMapper.readValue(src: InputStream): List<Checklist> defined in com.fasterxml.jackson.module.kotlin
public inline fun <reified T> ObjectMapper.readValue(src: Reader): List<Checklist> defined in com.fasterxml.jackson.module.kotlin
public inline fun <reified T> ObjectMapper.readValue(src: URL): List<Checklist> defined in com.fasterxml.jackson.module.kotlin
public inline fun <reified T> ObjectMapper.readValue(src: ByteArray): List<Checklist> defined in com.fasterxml.jackson.module.kotlin
public inline fun <reified T> ObjectMapper.readValue(content: String): List<Checklist> defined in com.fasterxml.jackson.module.kotlin
Therefore, I am outsmarted with my little Kotlin knowledge. For the sake of brevity I'd prefer not to explicitly parse every result in every test with the ObjectMapper, but I'd also be glad to make this work just in some way.