0

Ktor clientの上にサービスを作成しています。私のペイロードは XML であり、クライアントの簡略化されたバージョンは次のようになります。

class MavenClient(private val client : HttpClient) {

    private suspend fun getRemotePom(url : String) =
        try{ MavenClientSuccess(client.get<POMProject>(url)) }catch (e: Exception) { MavenClientFailure(e) 
    }

    companion object {
        fun getDefaultClient(): HttpClient {
            return HttpClient(Apache) {
                install(JsonFeature) {
                    serializer = JacksonSerializer(jackson = kotlinXmlMapper)
                    accept(ContentType.Text.Xml)
                    accept(ContentType.Application.Xml)
                    accept(ContentType.Text.Plain)
                }
            }
        }
    }
}

カスタム データ クラスにアタッチされたカスタム XMLMapper の使用に注意してください。

このクラスをテストし、ドキュメンテーションに従いたいと思います。

テストクライアントの次のコードになります。

private val mockClient = HttpClient(MockEngine) {
    engine {
        addHandler { request ->
            when (request.url.fullUrl) {
                "https://lengrand.me/minimal/1.2/minimal-1.2.pom" -> {
                    respond(minimalResourceStreamPom.readBytes()
                    , headers = headersOf("Content-Type" to listOf(ContentType.Application.Xml.toString())))
                }
                "https://lengrand.me/unknown/1.2/unknown-1.2.pom" -> {
                    respond("", HttpStatusCode.NotFound)
                }
                else -> error("Unhandled ${request.url.fullUrl}")
            }
        }
    }
    // TODO : How do I avoid repeating this again ? That's my implementation?!
    install(JsonFeature) {
        serializer = JacksonSerializer(jackson = PomParser.kotlinXmlMapper)
        accept(ContentType.Text.Xml)
        accept(ContentType.Application.Xml)
        accept(ContentType.Text.Plain)
    }
}
private val Url.hostWithPortIfRequired: String get() = if (port == protocol.defaultPort) host else hostWithPort
private val Url.fullUrl: String get() = "${protocol.name}://$hostWithPortIfRequired$fullPath"

private val mavenClient = MavenClient(mockClient)

Mapper 自体は直接テストしているので、今は心配していません。しかし、動作をテストするためにクライアントの完全なロジックを本質的に複製しなければならないことは、私を悩ませていますか? たとえば、明日Jsonに移行するとテストが失敗し、更新する必要があるため、これは非常に脆弱に思えます。たとえば、Response Validationの使用を開始した場合も同様です。これは、 を使用している別のクライアントにも当てはまります。これもdefaultRequest完全にコピーする必要があります。

private val mockClient = HttpClient(MockEngine) {
    install(JsonFeature) {
        serializer = JacksonSerializer(mapper)
        accept(ContentType.Application.Json)
    }
    defaultRequest {
        method = HttpMethod.Get
        host = "api.github.com"
        header("Accept", "application/vnd.github.v3+json")
        if (GithubLogin().hasToken()) header("Authorization", GithubLogin().authToken)
    }

私は間違ったことをしていますか?テストしすぎですか?これをどのように改善できるか、私は興味があります。

ご意見をお寄せいただきありがとうございます。

PS: 関係ありませんが、Ktor でのテストに関するページでは、implementation. testImplementationアプリケーションでライブラリを出荷するのを避けるために、代わりに使用する必要があるように聞こえますか?

4

1 に答える 1