Tyler Kinkade
03/27/2024, 10:54 PMclass SendData {
suspend fun postData(client: HttpClient): Boolean {
@Serializable
data class MyDataClass( val id: Int, val value: String)
val myData = MyDataClass(id = 0, value = "some value")
val response: HttpResponse = client.post {
url {
protocol = URLProtocol.HTTP
host = "localhost:8081"
path("myroute")
}
contentType(ContentType.Application.Json)
setBody(myData)
}
return (response.bodyAsText() == "OK")
}
}
SendDataTest.kt
class SendDataTest {
@Test
fun testPostData() = testApplication {
externalServices {
val port = "8081"
hosts(port) {
install(io.ktor.server.plugins.contentnegotiation.ContentNegotiation) { json() }
routing {
post("/myroute") {
call.respondText("OK", status = HttpStatusCode.OK)
}
}
}
}
val testClient = createClient {
install(io.ktor.client.plugins.contentnegotiation.ContentNegotiation) { json() }
}
val result = SendData().postData(testClient)
assertTrue(result)
}
}
Throws exception:
io.ktor.server.testing.client.InvalidTestRequestException: Can not resolve request to <http://localhost:8081>. Main app runs at localhost:80, localhost:443 and external services are <http://localhost>
at app//io.ktor.server.testing.client.DelegatingTestClientEngine.execute(DelegatingTestClientEngine.kt:56)
at app//io.ktor.client.engine.HttpClientEngine$executeWithinCallContext$2.invokeSuspend(HttpClientEngine.kt:99)
at app//kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at app//kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at app//kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
at app//kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:100)
at app//kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
at app//kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
at app//kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
at app//kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
Log:
2024-03-28 07:43:46.886 [Test worker @coroutine#1] TRACE i.k.c.p.c.ContentNegotiation - Adding Accept=application header for <http://localhost:8081/myroute>
2024-03-28 07:43:46.909 [Test worker @coroutine#1] TRACE i.k.c.p.c.ContentNegotiation - Converted request body using io.ktor.serialization.kotlinx.KotlinxSerializationConverter@5bcde458 for <http://localhost:8081/myroute>
2024-03-28 07:43:46.910 [Test worker @coroutine#1] TRACE i.ktor.client.plugins.HttpPlainText - Adding Accept-Charset=UTF-8 to <http://localhost:8081/myroute>
2024-03-28 07:43:46.915 [Test worker @coroutine#1] TRACE i.k.c.plugins.defaultTransformers - Transformed with default transformers request body for <http://localhost:8081/myroute> from class io.ktor.http.content.TextContent
2024-03-28 07:43:46.953 [Test worker @coroutine#1] TRACE i.k.client.plugins.HttpCallValidator - Processing exception io.ktor.server.testing.client.InvalidTestRequestException: Can not resolve request to <http://localhost:8081>. Main app runs at localhost:80, localhost:443 and external services are <http://localhost> for request <http://localhost:8081/myroute>
What do I need to do differently? 🤔Aleksei Tirman [JB]
03/28/2024, 8:01 AMexternalServices {
hosts("<http://localhost:8081>") {
// ...
}
}
Tyler Kinkade
03/28/2024, 8:27 AM