I’m trying to test ktor, but got this error: ```S...
# ktor
j
I’m trying to test ktor, but got this error:
Copy code
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See <http://www.slf4j.org/codes.html#StaticLoggerBinder> for further details.

No transformation found: class io.ktor.utils.io.ByteBufferChannel -> class kotlin.collections.List
with response from <http://localhost/fuel?state=RIO+DE+JANEIRO>:
status: 202 Accepted
response headers: 
Content-Type: application/json

io.ktor.client.call.NoTransformationFoundException: No transformation found: class io.ktor.utils.io.ByteBufferChannel -> class kotlin.collections.List
with response from <http://localhost/fuel?state=RIO+DE+JANEIRO>:
status: 202 Accepted
response headers: 
Content-Type: application/json

	at app//io.ktor.client.call.HttpClientCall.bodyNullable(HttpClientCall.kt:93)
	at app//jhonatan.sabadi.combustivel.datasource.client.fuel.FuelClient.getFuels(FuelClient.kt:45)
	at app//jhonatan.sabadi.combustivel.datasource.client.fuel.FuelClient$getFuels$1.invokeSuspend(FuelClient.kt)
	at app//kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at app//kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at app//kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
	at app//kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
	at app//kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
	at app//kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
	at app//kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
	at app//kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
	at app//client.FuelClientTest.receive success when get fuels list(FuelClientTest.kt:99)
	at java.base@11.0.14/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base@11.0.14/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base@11.0.14/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base@11.0.14/java.lang.reflect.Method.invoke(Method.java:566)
	at app//org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at app//org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at app//org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at app//org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at app//org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at app//org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at app//org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at app//org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at app//org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at app//org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at app//org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at app//org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at app//org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at app//org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at app//org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at app//org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
	at java.base@11.0.14/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base@11.0.14/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base@11.0.14/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base@11.0.14/java.lang.reflect.Method.invoke(Method.java:566)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
	at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
My test:
Copy code
private val mockEngine = MockEngine {
        respond(
            content = ByteReadChannel(jsonResponse),
            status = HttpStatusCode.Accepted,
            headers = headersOf(HttpHeaders.ContentType, "application/json")
        )
    }

    private val httClient = HttpClient(mockEngine)
    private val fuelClient = FuelClient(httClient)


    @Test
    fun `receive success when get fuels list`() = runTest {
        val fuels = fuelClient.getFuels(FuelRequestParams(state = "RIO DE JANEIRO"))
        val fuel = fuels[0]
        val expectedCnpj = "04.041.907/0001-50"
        assertEquals(expectedCnpj, fuel.cnpj)
    }
My client:
Copy code
override suspend fun getFuels(fuelRequestParams: FuelRequestParams): List<FuelDto> {
        val response = httpClient.get(Urls.Fuel.base) {
            url {
                parameter(Urls.Fuel.Params.state, fuelRequestParams.state)
                parameter(Urls.Fuel.Params.city, fuelRequestParams.city)
                parameter(Urls.Fuel.Params.neighbor, fuelRequestParams.neighbor)
            }
        }
        return response.body()
    }
client:
Copy code
httpClient {
            install(ContentNegotiation) {
                json(Json {
                    prettyPrint = true
                    isLenient = true
                    ignoreUnknownKeys = true
                })
            }
            defaultRequest {
                url(Urls.getBaseUrl(UrlEnv.DEV))
            }
        }
🧵 3
s
You should add one of the several SLF4J implementations, as Ktor uses their APIs to log stuff on the JVM. Check out https://ktor.io/docs/client-logging.html for more info.
For example, you can add the org.slf4j:slf4j-simple dependency, which logs to the console, or slf4j-android, which logs using LogCat on Android.
c
You cannot
respond
a ByteReadChannel if you set the header to
application/json
and use the JSON content negotiation. Return a string that could be serialized. @sindrenm the logger is just a “warning”. KTOR will fallback to the “NOP” logger.
Also please use the a thread if you post code snippets.
2
j
Finally i found a solution… I was use a Builder class to create httpclient, but not using on unit test
I started to receive httpEngine on builder
s
Oh, my bad, I didn't see the actual error in the stack trace (half blame being on my phone). 😅
😅 1
j
Now ia can respond with body<Type> and get test passed
Its ok rsrs, thank you all for trying to help me
352 Views