hermanjakobsen
hermanjakobsen

Reputation: 151

Test server endpoints on a Kafka Streams application built with Ktor

I have a simple Kafka Streams application built with Ktor. The Application.kt looks like

fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)

fun Application.module() {
    install(Routing) {
        healthController()
    }
    val stream = createStream()
    stream.start()
}

where

fun Route.healthController() {
    get("/health") {
        call.respond("I'm alive")
    }
}

I would like to write unit tests to test the endpoints of my application (i.e. /health). I have created the following unit test

@Test
    fun `Should get answer from health endpoint`() = testApplication {
        val response = client.get("/health")
        assertEquals(HttpStatusCode.OK, response.status)
        assertEquals("I'm alive", response.bodyAsText())
    }

This unit test works fine as long as the stream started in Application.kt does not use a KTable (at least a global KTable - I have not tested with a local KTable). If the stream uses a KTable, the unit test will never end as the stream will run indefinitely. This causes trouble in the GitLab pipeline where all the unit tests are executed.

Is there a "best practice" for testing the endpoints of a Kafka streams application built with Ktor? Especially, if the stream topology includes a KTable?

Upvotes: 0

Views: 315

Answers (1)

OneCricketeer
OneCricketeer

Reputation: 192023

In unit tests, you should be using Kafka Streams's TopologyTestDriver.

If you want to run integration tests for an RPC layer over Kafka's Interactive Streams, it shouldn't matter if the stream is indefinitely running (that's the point of running Streams). The topology should be running in a background thread, and not block your tests or HTTP/RPC server.

Ideally, you have a way to inject a Topology or StreamsBuilder into the Application rather than both creating and starting in your main method.

Upvotes: 1

Related Questions