Hi guys, i want to setBody to handleRequest for te...
# ktor
e
Hi guys, i want to setBody to handleRequest for test. How should i do?
Copy code
handleRequest(<http://HttpMethod.Post|HttpMethod.Post>, "/login") {
    addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
    addHeader(HttpHeaders.Accept, ContentType.Application.Json.toString())
    //setBody("{\"username\": \"emirhan\", \"password\": \"1234\"}")
    setBody(listOf("username" to "emirhan", "password" to "1234").toString())
}
i'm receiving: io.ktor.features.CannotTransformContentToTypeException: Cannot transform this request's content to com.emirhan.model.UserRequest My data class UserRequest is like:
Copy code
@Serializable
data class UserRequest(
    val username: String,
    var password: String
)
In route im receiving body like:
Copy code
val userRequest = call.receive<UserRequest>()
I also try this too
Copy code
setBody(Json.encodeToString(UserRequest("emirhan","1234")))
getting same error
h
Just log your body: Currently you produce this:
Copy code
[(username, emirhan), (password, 1234)]
, but you need this:
Copy code
{
  "username": "emirhan",
  "password": 1234
}
. Why do you handle serialization yourself? How do you get this body normally?
Using Json should work 🤔
Can you please add a logger to get the real body set to your server?
e
I'm trying this in test i add CallLogging for my test method but not logging
Copy code
install(CallLogging) {
    level = <http://Level.INFO|Level.INFO>
    format {
        val status = it.response.status()
        val httpMethod = it.request.httpMethod.value
        "Status: $status, HTTP method: $httpMethod"
    }
    filter { call -> call.request.path().startsWith("/") }
}
but with FormUrlEncoded it works well. I can setBody like:
Copy code
setBody(listOf("username" to "emirhan", "password" to "1234").formUrlEncode())
h
This test works...
Copy code
@Serializable
data class A(val s: String, val p: Int)

class Testing {
    @Test
    fun a() = withTestApplication({
        install(ContentNegotiation) {
            json()
        }
        install(CallLogging)
        routing {
            get("works") {
                call.respondText("Works")
            }
            get("bam") {
                error("BAM")
            }
            post("p") {
                val body = call.receive<A>()
                println(body)
                call.respond(body)
            }
        }
    }) {
        val content = handleRequest(<http://HttpMethod.Post|HttpMethod.Post>, "p") {
            addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString())
            setBody(Json.encodeToString(A("a", 42)))
        }.response.content
        assertEquals("""{"s":"a","p":42}""", content)
    }
}
e
what is your ktor version?
h
1.6.6
plugins { kotlin("jvm") version "1.6.0" kotlin("plugin.serialization") version "1.6.0" } repositories { mavenCentral() } dependencies { implementation("io.ktorktor server cio1.6.6") implementation("io.ktorktor serialization1.6.6") runtimeOnly("ch.qos.logbacklogback classic1.2.7") testImplementation(kotlin("test")) testImplementation("io.ktorktor server test host1.6.6") }
e
I'm using ktor 1.6.5 and kotlin 1.5.32 because of Koin not supporting top versions and throwing NoSuchMethod exception
Doing same as you but still getting error, maybe this is about ktor or kotlin versions
h
Downgrading my sample does not throw any errors 😄 Wanna try it?
So something is broken in your test/implementation
e
Copy code
implementation("io.ktor:ktor-serialization:$ktor_version")
implementation("io.ktor:ktor-server-netty:$ktor_version")
testImplementation("io.ktor:ktor-server-tests:$ktor_version")
implementation("io.ktor:ktor-jackson:$ktor_version")
Copy code
setBody(Json.encodeToString(UserRequest("emirhan", "1234")))
Copy code
val userRequest = call.receive<UserRequest>()
dude i don't understand if you want to check here my repo 😂 https://github.com/Methdogg/KtorFirstProject/tree/develop
h
In your
testModule
you don't call
configureSerialization()
And BTW you should not use 2 different serialization libraries: I would remove
Jackson
and only use
kotlinx.serialization
e
you are a lifesaver i'm using jackson library because of openapi library
180 Views