Ktor¶
stove-ktor is the starter for applications built on Ktor. Stove starts the real Ktor application and keeps the test setup in one place.
Dependency¶
dependencies {
testImplementation(platform("com.trendyol:stove-bom:$version"))
testImplementation("com.trendyol:stove")
testImplementation("com.trendyol:stove-ktor")
}
Application Entrypoint¶
Expose a reusable run function and return the started Application. The exact shape depends on your DI framework:
fun main(args: Array<String>) {
run(args, shouldWait = true)
}
fun run(
args: Array<String>,
shouldWait: Boolean = false,
testModules: List<Module> = emptyList()
): Application {
val config = loadConfiguration<AppConfiguration>(args)
val applicationEngine = embeddedServer(Netty, port = config.port, host = "localhost") {
install(Koin) {
modules(appModule, *testModules.toTypedArray())
}
configureRouting()
}
applicationEngine.start(wait = shouldWait)
return applicationEngine.application
}
fun main(args: Array<String>) {
run(args, shouldWait = true)
}
fun run(
args: Array<String>,
shouldWait: Boolean = false,
testDependencies: (DependencyRegistrar.() -> Unit)? = null
): Application {
val config = loadConfiguration<AppConfiguration>(args)
val applicationEngine = embeddedServer(Netty, port = config.port, host = "localhost") {
install(DI) {
dependencies {
provide<MyService> { MyServiceImpl() }
testDependencies?.invoke(this)
}
}
configureRouting()
}
applicationEngine.start(wait = shouldWait)
return applicationEngine.application
}
Minimal Stove Setup¶
Stove()
.with {
ktor(
runner = { params -> run(params, shouldWait = false) },
withParameters = listOf("port=8080")
)
}
.run()
What You Get¶
- real Ktor startup from your own server bootstrap
bridge()support with automatic DI detection- easy composition with Kafka, databases, WireMock, tracing, and HTTP assertions
Bridge and DI Support¶
Ktor Bridge automatically detects which DI framework your application uses at runtime:
| DI Framework | Detection | Priority |
|---|---|---|
| Ktor-DI | dependencies { ... } is active in the application |
Preferred when both are present |
| Koin | install(Koin) { ... } is active |
Used when Ktor-DI is not active |
| Custom | Manual resolver provided via bridge { app, type -> ... } |
Explicit override |
Registering Test Dependencies¶
Pass test modules that override production beans:
Pass a lambda that registers test overrides (later provide<T> calls override earlier ones):
Using Bridge in Tests¶
stove {
using<UserService> {
val user = findById(123)
user.name shouldBe "John"
}
using<List<PaymentService>> {
forEach { service -> service.validate() }
}
}
See the Bridge documentation for complete usage patterns including multi-bean access, value capture, and generic type resolution.