https://kotlinlang.org logo
Title
n

napperley

03/21/2019, 4:23 AM
Trying to test the server (runs on a different host and port) via the Kotlin Test library, and have encountered a situation where when running a test it runs indefinitely. Below is the test logic:
import io.kotlintest.specs.FunSpec
import io.ktor.application.Application
import io.ktor.http.HttpMethod
import io.ktor.http.HttpStatusCode
import io.ktor.server.testing.handleRequest
import io.ktor.server.testing.withTestApplication
import kotlin.test.assertEquals

class RouteTest : FunSpec() {
    init {
        testHomeRouteExists()
    }

    private fun testHomeRouteExists() = test("homeRouteExists") {
        withTestApplication(Application::main) {
            with(handleRequest(HttpMethod.Get, "/")) {
                assertEquals(expected = HttpStatusCode.OK, actual = response.status())
                assertEquals(expected = "Battery Info Server\n", actual = response.content)
            }
        }
    }
}
Resolved the issue by restructuring server.kt file to the following:
// ...
fun main() {
    val env = applicationEngineEnvironment {
        module { main() }
        connector {
            host = GeneralSettings.host
            port = GeneralSettings.port
        }
    }
    <http://logger.info|logger.info>("Starting server (on http://${GeneralSettings.host}:${GeneralSettings.port})...")
    embeddedServer(factory = Netty, environment = env).start(true)
}

fun Application.main() {
    connectToDb()
    install(ContentNegotiation, setupJackson())
    install(StatusPages, setupStatusPages())
    routing {
        homeRoute(this)
        ownerExistsRoute(this)
        listOwnersRoute(this)
        setupSiteRoutes(this)
        setupSensorDataRoutes(this)
        sensorDataTimestampRangeRoute(this)
    }
}
// ...
d

dave08

03/24/2019, 5:25 AM
I had a similar problem when using two connectors for two different ports... which piece solved the problem exactly? Would it apply for two ports too?
n

napperley

03/24/2019, 8:23 PM
Before the restructuring there was no main module (Application::main) which was the missing piece to get testing in Ktor to work.
Since then I have created a separate testMain module that is used in tests which looks like the following:
fun Application.testMain() {
    install(ContentNegotiation, setupJackson())
    install(StatusPages, setupStatusPages())
    routing {
        homeRoute(this)
        setupOwnerRoutes(this, true)
        setupSiteRoutes(this, true)
        setupSensorDataRoutes(this, true)
    }
}
The connector is only applicable to the Production server. Ktor takes care of configuring the Test server. There is no need to provide a host and port.
d

dave08

03/25/2019, 11:09 AM
Oh... I used the new
port(8080) { ... }
route, and the tests seem to ignore it, I guess its a different problem then 😞