Ktor integration

Embed Mokksy directly inside a Ktor application for integration tests, internal API simulation, and authenticated stub routes.

If you already own a Ktor Application — a test harness with authentication middleware, custom plugins, or routes that must coexist with stubs — use the mokksy extension functions to mount stub handling directly, without allocating a second embedded server.

Application-level installation

Application.mokksy(server) installs SSE, DoubleReceive, and ContentNegotiation automatically, then mounts a catch-all route that dispatches every incoming request through the stub registry:

 1import dev.mokksy.mokksy.MokksyServer
 2import dev.mokksy.mokksy.mokksy
 3import io.ktor.server.engine.embeddedServer
 4import io.ktor.server.netty.Netty
 5
 6val server = MokksyServer()
 7server.get { path("/ping") } respondsWith { body = "pong" }
 8
 9embeddedServer(Netty, port = 8080) {
10    mokksy(server)
11}.start(wait = true)

Use this overload when Mokksy owns the entire application and you want the simplest possible setup.

Route-level installation

Route.mokksy(server) mounts the stub handler inside an existing route scope. Unlike the application-level overload, it does not install plugins — you are responsible for installing SSE, DoubleReceive, and ContentNegotiation on the surrounding application. This makes it suitable when Mokksy stubs coexist with real routes:

1routing {
2    get("/health") { call.respondText("OK") }
3    mokksy(server)
4}

To place stubs behind an authentication check, install the required plugins and wrap mokksy in an authenticate block:

 1install(SSE)
 2install(DoubleReceive)
 3install(ContentNegotiation) { json() }
 4install(Authentication) {
 5    basic("auth-basic") {
 6        validate { credentials ->
 7            if (credentials.name == "user" && credentials.password == "pass") {
 8              UserIdPrincipal(credentials.name)
 9            } else null
10        }
11  }
12}
13
14routing {
15    authenticate("auth-basic") { 
16        mokksy(server)
17    }
18}

Both extension functions accept any path pattern as a second parameter (default: "{...}", which matches all routes). Narrow the scope by passing a prefix:

1mokksy(server, path = "/api/{...}")