Closed niom closed 3 years ago
Ok, update on this one.
I poked around a little bit more. I get rid of the errors if I don't inject my dependencies as class variables but doing the inject inside the test function it self. Tests work at intellij level but then again when running all the tests with gradle the problem is at hand again.
class SomeTest : KoinTest {
private val someDependency by inject<Dependency>()
@Test
fun doTest() {
someDependency.doSomething() //this will fail
}
}
class SomeTest : KoinTest {
@Test
fun doTest() {
val someDependency by inject<Dependency>()
someDependency.doSomething() //this works ok in idea but fails in gradle
}
}
I poked this even further and now I can confirm that this is KTOR 1.5.x problem starting from KTOR 1.5.0 update.
I started from the 2.2.2 tag and worked my way first to upgrade Kotlin and coroutines to latest 1.4.x and everything worked. Then I upgraded the KTOR to 1.5.x and my tests started to fail.
So something has fundamentally changed in KTOR 1.5.x
I have to admit that this was a really painful to solve but I have some good news on this one. The problem is in KTOR server as I confirmed before. This happens due ktor for some very random reason enables development mode automatically and due that the ClassLoader gets mixed up in tests. My best guess is that it has something to do with their autoreload functionality.
I also found a bug report from ktor that helped me to solve this: https://youtrack.jetbrains.com/issue/KTOR-2306
ktor {
development = false
}
Hopefully that bug is some day fixed.
I would keep this bug open until the KTOR one is fixed.
Oh during by poking around I also tried to upgrade to Kotlin 1.5.0. That didn't end well. Got KoinAlreadyStarted errors and also ClassCastException from tests. Just for heads up for the future.
I'm updating to Ktor 1.6.0, let me know if you can reproduce it
Tried to upgrade to ktor 1.6.0 my self. Our tests failed: java.lang.reflect.InvocationTargetException at NativeMethodAccessorImpl.java:-2 Caused by: org.koin.core.error.KoinAppAlreadyStartedException at GlobalContext.kt:44
Confirmed that upgrading to koin 3.0.2 this issue was fixed and I could upgrade to both KTOR 1.6.0 and to Kotlin 1.5.10.
great 👍
Hello, so I have the same issue but with the new Ktor 2.0.1 using Koin 3.2. The problem is when I run tests that inject dependencies (for example in the Route function).
This is the injection that is failing.
fun Route.artworkRouting() {
val idService by inject<IdService>()
route("/artworks") {
get {
}
}
}
this is the test:
class AuthenticationTest : WordSpec(), KoinTest {
val dataSource = install(JdbcTestContainerExtension(container)) {
poolName = "myconnectionpool"
maximumPoolSize = 8
idleTimeout = 10000
}
private val testDbModule = module {
single { dataSource }
single<Jdbi> {
Jdbi.create(get<DataSource>()).installPlugins().registerColumnMapper(LocalDateTimeMapper())
.registerArgument(LocalDateTimeArgumentFactory())
}
}
private val applicationConfig = ApplicationConfig("test-application.conf")
private val testHttpModule = module {
single { setupClient(mockEnginePB, applicationConfig) }
}
override fun extensions(): List<Extension> =
listOf(KoinExtension(listOf(testDbModule, testHttpModule, RepositoryModule)))
lateinit var jwt: JwtToken
init {
"JWT Authorization" should {
"Be authorized on correct token" {
// when
testApplication {
application { Application::testModule }
environment {
config = ApplicationConfig("test-application.conf")
}
val client = createClient { install(ContentNegotiation) { json() } }
val response = client.get("/api/artworks?artistName=%25Picasso") {
header(HttpHeaders.Authorization, "Bearer ${jwt.token}")
}
// then
response shouldHaveStatus HttpStatusCode.NotFound
}
}
}
}
This is happening only with the new testFramework. When I run the old withApplication there is no issue.
Describe the bug After I tried to upgrade our koin Ktor project from 2.2.2 to 3.0.1 I get really weird exception from some of my tests.
java.lang.ClassCastException: class foo.bar.FooBar cannot be cast to class foo.bar.FooBar (foo.bar.FooBar is in unnamed module of loader io.ktor.server.engine.OverridingClassLoader$ChildURLClassLoader @240f6c41; foo.bar.FooBar is in unnamed module of loader 'app')
This is a multimodule project and if I transfer the class FooBar to a different module the tests start to act normal but not in all cases. Smells like race condition or some how the ClassLoaderContext gets changed or corrupted.
Also smells a lot that something has happened in KTOR 1.5.x upgrade to coroutine handling and that's not handled correctly in KTOR. I have this hunch because running tests through gradle gives development mode method missing exception and after upgrading our KTOR dependencies to 1.5.4 I get this weird ClassCastException again.
To Reproduce I have no idea how to reproduce this in any easy manner.
Expected behavior Class loading would work as expected
Koin project used and used version (please complete the following information): Koin 3.0.1 produces this weird exception. With 2.2.2 everything works as expected
Additional moduleDefinition I start the koin with Ktor server instance an try to override some of the modules with test versions at the koin context star up. I chain the module configurations from the multimodule configuration with using modules() chaining.
Really would like to get new ideas how to poke this around. I feel really stuck with this one.