我的应用程序设置为在服务器开始运行时立即加载数据库 与
createdAtStart = true
val dbModule = module {
single(createdAtStart = true) {
Db(
driverClassName = "org.h2.Driver", jdbcURL = "jdbc:h2:file:./build/db"
)
}
正常运行服务器时,我不需要在任何地方手动注入数据库来初始化它,因为它是自动完成的并且依赖于数据库对象获取
此外,用于测试的数据库是内存数据库,可以使用 koin 轻松注入单元测试
factory(qualifier = named("test")) { params ->
Db(
driverClassName = "org.h2.Driver",
jdbcURL = "jdbc:h2:mem:${params.get<String>()};DB_CLOSE_DELAY=-1"
)
}
问题
在测试整个应用程序时,即使用 ktor 的服务器路由
testApplication
,默认数据库是直接注入的,我无法注入测试数据库。
// test is empty because i realised i can't inject my test db
class ApplicationTest: KoinTest {
@Test
fun testRoot() = testApplication {
val response = client.get("/")
assertEquals(HttpStatusCode.OK, response.status)
}
}
我认为我的应用程序设计和文件结构存在缺陷,因为这是我第一次使用 ktor
如何将正确的数据库放入测试应用程序
我必须稍微重组我的代码库。
主数据库不再提前创建
// koin.kt
val dbModule = module {
single {
Db(
driverClassName = "org.h2.Driver", jdbcURL = "jdbc:h2:file:./build/db"
)
}
factory(qualifier = named("test")) { params ->
Db(
driverClassName = "org.h2.Driver",
jdbcURL = "jdbc:h2:mem:${params.get<String>()};DB_CLOSE_DELAY=-1"
)
}
}
依赖注入和数据库配置被分成不同的模块,并基于主模块上的测试标志来使用
// application.kt
fun Application.di() {
install(Koin) {
slf4jLogger()
modules(dbModule)
}
}
fun Application.configureDb() {
val db: Db by inject()
TransactionManager.defaultDatabase = db.database // this line isn't really need as exposed uses last open db connection
}
fun Application.main(testing: Boolean = false) {
if (!testing) {
di()
configured()
}
}
class ApplicationTest : KoinTest {
private lateinit var db: Db
@BeforeEach
fun `setup db`() {
db = get {
parametersOf("")
}
TransactionManager.defaultDatabase = db.database
}
@Test
fun testRoot() = testApplication {
application {
module(testing = true)
}
environment {
config =
ApplicationConfig("test_application.yaml") // loads environment variables for test
val response = client. Get("/")
assertEquals(HttpStatusCode.OK, response.status)
}
companion object {
@JvmStatic
@BeforeAll
fun `start koin`(): Unit {
startKoin {
modules(dbModule)
}
}
}
}
请参阅这些链接以获取有关所使用的某些方法的更多说明
testApplication()
在Ktor中设置Koin?