0

I've using Kotest recently and I hadn't had any issues, but recently I was trying some annotations for dependency injection so to simplify the problem I created some basic classes with some methods that just print some messages, just for the sake of learning how to use Kotest and Mockk, but during the testing, I ran with the exception that the variable hasn't been initialized when trying to run the test.

These are my classes

class DefaultClass : AbstractClass() {
    private val anotherClass: AnotherClass = AnotherClass()

    fun testMethod(value: String): String {
        val normalizeValue = value.trim().lowercase().replace(Regex("[^ A-Za-z\\d]*"), "")
        return runBlocking {
            anotherClass.someOtherMethod()
            callsProtectedMethod(normalizeValue)
        }
    }

    private suspend fun callsProtectedMethod(value: String) = coroutineScope {
        println("Original method")
        returnDefaultString(value)
    }
}

AnotherClass

class AnotherClass {

    fun someOtherMethod(): Unit {
        println("SomeOtherMethod original")
    }
}

Test

class DefaultClassTest : FunSpec({


context("Testing DefaultClass") {
    @MockK
    lateinit var anotherClass: AnotherClass

    @OverrideMockKs
    lateinit var defaultClass: DefaultClass

    beforeContainer {
        MockKAnnotations.init(this)
    }

    test("testing mocks") {
        defaultClass.testMethod("some method")
    }
}

I've changed the initialization to beforeTest, taken it out of the context, and also use beforeContainer, beforeTest, beforeSpec, but none of these work... every time I still get lateinit property defaultClass has not been initialized

So, I recreated the same test using JUnit and I don't have this issue.

    class DefaultClassJUnitTest {

    companion object {
        @MockK
        lateinit var anotherClass: AnotherClass

        @OverrideMockKs
        lateinit var defaultClass: DefaultClass

        @BeforeAll
        @JvmStatic
        fun setup() {
            MockKAnnotations.init(this)
        }
    }

    @Test
    fun `Testing with JUnit`() {
        every { anotherClass.someOtherMethod() } answers {
            println("Mocking another class")
        }
        val value = defaultClass.testMethod("some method")
    }
}

So I'm pretty sure that I'm doing something wrong when using Kotest. I hope anyone might help me, thanks...

1 Answers1

0

I think MockK is probably not looking for variables defined within function scopes. If you want to use the annotations, you likely have to move them to the companion object, like this:

class DefaultClassTest : FunSpec({

context("Testing DefaultClass") {
    beforeContainer {
        MockKAnnotations.init(this)
    }

    test("testing mocks") {
        defaultClass.testMethod("some method")
    }
}


}) {
  companion object {
    @MockK
    lateinit var anotherClass: AnotherClass

    @OverrideMockKs
    lateinit var defaultClass: DefaultClass
  }
}
Emil Kantis
  • 1,069
  • 7
  • 17