Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin Mockk Error: Missing calls inside verify { ... } block

I already read some issues with this or a similar error message (it is also ocurring for every {}), but none of them took me to a success result.

Any hints or suggestions on how to get this to work?

Here is my setup and the Unit Test itself:

compileSdkVersion 29
defaultConfig {
   minSdkVersion 19
   targetSdkVersion 29
   testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

MockK version: 1.9.3.kotlin12
OS: Android
Kotlin version: 1.3.61
JDK version: jdk1.8.0_212
JUnit version: 4.12
Type of test: unit test

The stacktrace of the error:

io.mockk.MockKException: Missing calls inside verify { ... } block.

    at io.mockk.impl.recording.states.VerifyingState.checkMissingCalls(VerifyingState.kt:52)
    at io.mockk.impl.recording.states.VerifyingState.recordingDone(VerifyingState.kt:21)
    at io.mockk.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:47)
    at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:60)
    at io.mockk.impl.eval.VerifyBlockEvaluator.verify(VerifyBlockEvaluator.kt:30)
    at io.mockk.MockKDsl.internalVerify(API.kt:118)
    at io.mockk.MockKKt.verify(MockK.kt:139)
    at io.mockk.MockKKt.verify$default(MockK.kt:136)

My Unit Test:

@Test
fun logout_clearsDatabase() {
    coroutineTestRule.testDispatcher.runBlockingTest {

        // ARRANGE
        database.dataDao().insert(listOf(DataDummies()))

        // ACT
        sut.logout()

        // ASSERT
        verify { database.clearAllTables() }
    }
}

I have no clue what I did wrong here. database.clearAllTables() is a method provided by Room. The testDispatcher is a TestCoroutineDispatcher() provided by the androidx testing library.

UPDATE / ANSWER

Thanks to the input of @Juan Cruy Soler I changed the way of injecting the database. I did not return the real room database, instead I return a spy of it. That way the spy is injected into the SUT as well as into my test class. After that change the test runs as excpected. I this a feasible solution to my problem? Does it make sense to let the (Testing-)DependencyInjection create a spy?

like image 628
muetzenflo Avatar asked Feb 19 '20 19:02

muetzenflo


People also ask

What is the best mocking library for Kotlin apps?

MockK seems to be on its way to become the defacto mocking library for Kotlin apps. With a syntax based heavily around lambdas, it just looks like a DSL, as you can see in this example taken directly from their page: val car = mockk < Car >() every { car.drive( Direction. NORTH) } returns Outcome. OK car.drive( Direction.

How to mock private functions in Kotlin?

This is standard Kotlin behaviour that may be unpredictable. Use Tools -> Kotlin -> Show Kotlin Bytecode or check .class files in JAR archive to detect such names. From version 1.9.1, more extended vararg handling is possible: IF you need to mock private functions, you can do it via a dynamic call.

How to mock singleton instances in Kotlin?

Kotlin provides an easy way to declare a singleton by using the object keyword: However, most of the mocking libraries have a problem with mocking Kotlin singleton instances. Because of this, MockK provides the mockkObject method. Let’s take a look:

How to detect unpredictable class names in a Kotlin file?

For example the extension function File.endsWith () has a totally unpredictable classname: This is standard Kotlin behaviour that may be unpredictable. Use Tools -> Kotlin -> Show Kotlin Bytecode or check .class files in JAR archive to detect such names. From version 1.9.1, more extended vararg handling is possible:


2 Answers

database should be mock or a spy to call verify on it.
I assume that it's not a mock because you are calling the method dataDao() in a previous line.

  • If you don't want to mock it you can use a real database instead, check that database.dataDao().getData() returns an empty list and remove the verify line.
  • If you mock it, then you can remove this line database.dataDao().insert(listOf(DataDummies()))
like image 61
Juan Cruz Soler Avatar answered Nov 03 '22 01:11

Juan Cruz Soler


You should use spyk to simulate a real scenario.

val database = spyk<YouDataBaseReference>()

Doing that, you'll be able to use functions.

like image 23
Jhonatan Sabadi Avatar answered Nov 03 '22 01:11

Jhonatan Sabadi