Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockk Missing calls inside every { ... } block

I'm stuck trying to mock some stuff with mockk:

I have the following setup on gradle

root:
  |-- App (just a sample app for the SDK)
  |-- SDK (SDK we develop) << apply plugin: 'com.android.library'
       |-- SDKimpl.kt
  |-- Foo (wrapper around a .jar library) << apply plugin: 'com.android.library'
       |-- Foo.kt

So I'm writing an androidTest for the SDK and trying to mock Foo.kt. There's nothing unusual about Foo class, just direct class Foo(private val someParams) {

So using androidTestImplementation "io.mockk:mockk-android:1.8.13" the mock goes:

val mock: Foo = mockk()
// val mock: Foo = mockkClass(Foo::class) // also tried this
every { mock.getData() } returns listOf("1", "2", "3")

I'm always getting the following crash:

io.mockk.MockKException: Missing calls inside every { ... } block.
at io.mockk.impl.recording.states.StubbingState.checkMissingCalls(StubbingState.kt:14)
at io.mockk.impl.recording.states.StubbingState.recordingDone(StubbingState.kt:8)
at io.mockk.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:42)

Also tried just to gather information:

  • running inside JVM test folder. It gets mocked without issues, but I can't run my test as JVM
  • running androidTest inside Foo module. Got the same crash
  • using mockkClass(Foo::class). Got some crash
  • using annotation @MockK and MockKAnnotations.init(this). Got some crash.
  • added Log.d before every { line and inside getData() method and it seems the actual real method from the class is getting called during the mock setup. That seems super weird to me.

Any idea what's going wrong here?

edit:

as requested, full code. I'm current working on an isolated project to try to isolate the error, so Foo is just:

class Foo {

    fun getData(): String {
        Log.d(TAG, "invoked foo.getData()")
        return "trolololo"
    }

}

and then I have FooTest in androidTest:

class FooTest {

    @Test
    fun mock_foo() {
        val foo = mockk<Foo>()
        every { foo.getData() } returns "zero"
        assertEquals("zero", foo.getData())
    }

}
like image 254
Budius Avatar asked Nov 20 '18 11:11

Budius


3 Answers

It seems to be a Mockk opened issue: https://github.com/mockk/mockk/issues/182

2 possible quick fixes (pick one):

  1. Run the Instrumented Tests in an emulator >= Android-P
  2. Set Foo class as open (and the method(s) you want to mock too)
like image 71
Phil Avatar answered Nov 20 '22 12:11

Phil


Try to check the official guide and see what is missing.

In my case, I tried to mock an extension in Kotlin but missed the mockkStatic

fun Date.asMyTime() : DateTime = DateTime(this, DateTimeZone.getDefault())

mockkStatic("packageName.FileNameKt") // This is what I was missing
every {
    DateTime().asMyTime()
} returns mock(DateTime::class.java)
like image 36
Allen Avatar answered Nov 20 '22 13:11

Allen


In my case I forgot to spyk the class I was applying every {...} to. 😳

val presenter = spyk(MyPresenter())

every { view.myFun(any()) } returns Unit
like image 15
Tom Avatar answered Nov 20 '22 11:11

Tom