Уменьшение дублирования кода при тестировании KtorClient
Я создаю сервис поверх клиента Ktor. Моя полезная нагрузка - это 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 завтра. То же самое, если я, например, начну использовать проверку ответа. Это еще более верно для другого клиента, где я использую
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
вместо этого, чтобы не отправлять библиотеку вместе с моим приложением?
1 ответ
В