简体   繁体   中英

Mockk call lambda when other method is called

I'm trying to create this MockController with mockk to avoid create a new class for testing.

Is possible to do that?

class MockController : IController {
    override lateinit var output: (String) -> Unit

    override fun start() {
        output("OK")
    }
}

Class to test:

class ClassToTest(
    private val controller: IController,
    private val output: (String) -> Unit
){

    fun start() {
        controller.output = { result ->
            output(result)
        }
        controller.start()
    }
}

Then I use like this TEST example:

 @Test
    fun checkOutputIsCalled() {
      runBlocking {
        var outputCalled = false

        val outputClassToTest: (String) -> Unit = {
          outputCalled = true
        }

        val classToTest = ClassToTest(MockController(), outputClassToTest)
        classToTest.start()

        delay(1000)
        assert(outputCalled)
    }
}

I'm trying to update:

 @Test
    fun checkOutputIsCalled() {
      runBlocking {
        val controller = spyk<IController>()

        var outputCalled = false

        val outputClassToTest: (String) -> Unit = {
          outputCalled = true
        }

        val classToTest = ClassToTest(controller, outputClassToTest)

        every { controller.start() } answers {
                controller.output.invoke("OK")
        } //When I execute the test, output is null because yet doesn't exist the output creted inside ClassToTest

        classToTest.start()

        delay(1000)
        assert(outputCalled)
    }
}

When I execute the test, output is null because yet doesn't exist the output creted inside ClassToTest

How this could be after the output assign?

Thanks!

You should mock your output object and your Controller. Once done, tell your mocked controller to return the mocked output when property is called. Right after the start() invocation you can verify that output lambda was invoked. Please note that all your mocks must be relaxed.

class ClassToTestTesting {

    companion object {
        const val INVOCATION_PARAM = "OK"
    }

    @Test
    fun test() = runBlocking {
        val paramOutput: (String) -> Unit = mockk(relaxed = true)

        val controller: IController = mockk(relaxed = true) {
            every { output } returns paramOutput
            every { start() } answers { output.invoke(INVOCATION_PARAM) }
        }

        val classToTest = ClassToTest(
            controller,
            paramOutput
        )

        classToTest.start()
        verify { paramOutput(INVOCATION_PARAM) }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM