[Ktor]rest-assuredでList<Any>を取得してAnyを利用する


Ktorのテストコードでrest-assuredを用いてAPI呼び出しをする際の話。

List形式で受け取りたい場合に、Extractでto<List<Any>>()を使用した後に
アサーションのために値を利用しようとすると、Jacksonのデシリアライズに失敗してClassCastExceptionとなってしまうので、その対策。

今回はrest-assuredのkotlin拡張を利用していますが、利用しなくても特に問題はありません。

Gradle

    testImplementation "org.assertj:assertj-core:3.14.0"
    testImplementation "io.rest-assured:rest-assured:4.1.2"
    testImplementation group: 'io.rest-assured', name: 'kotlin-extensions', version: '4.1.2'

Test

@Test
fun testGetHoge() {
    var hoges = mutableListOf<Hoge>()
    transaction {
        hoges.add(Hoge.new { name = "taro" })
        hoges.add(Hoge.new { name = "jiro" })
    }

    val results = Given {
        contentType(ContentType.JSON)
    } When {
        get("/hoge")
    } Then {
        statusCode(200)
    } Extract {
        // resultsの型は、(Mutable)List<HogeData>!になる
        body().jsonPath().getList(".", HogeData::class.java)
    }

    assertEquals(hoges.size, results.size())
    // to<List<HogeData>>()だと、results[0].nameに失敗する
    assertEquals(hoges[0].name, results[0].name)
    assertEquals(hoges[1].name, results[1].name)
}

関連記事とか

java - java.lang.ClassCastException:java.util.LinkedHashMapをcom.testing.models.Accountにキャストできません
https://ja.coder.work/so/java/67788

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.testing.models.Account
https://stackoverflow.com/questions/28821715/java-lang-classcastexception-java-util-linkedhashmap-cannot-be-cast-to-com-test