Mockk Missing calls inside every { ... } block
Asked Answered
M

11

54

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())
    }

}
Mandarin answered 20/11, 2018 at 11:4 Comment(0)
H
21

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)
Halfcock answered 24/12, 2018 at 17:7 Comment(0)
B
20

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)
Bewitch answered 17/5, 2019 at 13:25 Comment(2)
Thanks for mockkStatic("packageName.FileNameKt") when test extension method! Did you mean mockk, not mock in the last line? – Ultramicrometer
Instead of mockkStatic("packageName.FileNameKt") you can write: mockkStatic(FileName::class.java.name + "Kt"). – Ultramicrometer
N
19

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

val presenter = spyk(MyPresenter())

every { view.myFun(any()) } returns Unit
Nostalgia answered 2/4, 2020 at 22:45 Comment(2)
Can we add any() to spyk – Klaipeda
@AkshayHazari spyk is used to add mocking and verification abilities to "real" objects. Anything that can be done with mockks can be done on spyk'd objects, such as every{}, verify{} etc. – Nostalgia
R
7

In my case, I've missed

@Before
fun setUp() {
    MockKAnnotations.init(this)
}
Receivership answered 3/6, 2020 at 11:24 Comment(0)
O
7

In my case I tried to mock using mock() function instead mockk() (double k)

Obtect answered 16/11, 2020 at 13:8 Comment(0)
B
5

Make sure the object is really a mock, not the real object.

For instance:

- Sdk sdk = Sdk()
+ Sdk sdk = mockk()
  every { sdk.crypto } returns mockk()
Betatron answered 10/11, 2020 at 2:26 Comment(0)
B
4

My problem was that I used a java class without getters

public class KeyStorePasswordPair {
    public KeyStore keyStore;
    public String keyPassword;

    public KeyStorePasswordPair(KeyStore keyStore, String keyPassword) {
        this.keyStore = keyStore;
        this.keyPassword = keyPassword;
    }
}

I needed to add getters for the variables to make mockking work:

public class KeyStorePasswordPair {
    public KeyStore getKeyStore() {
        return keyStore;
    }

    public String getKeyPassword() {
        return keyPassword;
    }

    private KeyStore keyStore;
    private String keyPassword;

    public KeyStorePasswordPair(KeyStore keyStore, String keyPassword) {
        this.keyStore = keyStore;
        this.keyPassword = keyPassword;
    }
}

Betatron answered 3/1, 2022 at 9:16 Comment(0)
J
2

Mockk Missing calls inside every { ... } block

may also be thrown when you have an every block defined on an object that is not a mockk, for example:

You define stub behavior like this

every { foo.getData() } returns DATA

and then try to:

every { DATA.getVersion() } returns VERSION

Where DATA and VERSION objects are declared (and instantiated) in the test class.

The error message is not very informative and a bit misleading in that case.

Jarita answered 8/8, 2022 at 10:58 Comment(0)
S
0

If the method or attribute that you want to mock inside the every block is final, then that's the reason.

Sincere answered 18/12, 2023 at 10:36 Comment(0)
F
0

Another reason this would be thrown is if you try to use every on a property. For example

class Car {
    var seats = 4
}
val mockCar  = mockk<Car> {
    every { seats } return 2
}

What you should do is to assign property directly:

mockCar.seats = 2

Also check the documentation

Floatage answered 20/5 at 10:30 Comment(0)
B
-6

try like this

`when`(mock.getData()).thenReturn(listOf("1", "2", "3"))
Balanced answered 3/3, 2021 at 10:15 Comment(2)
when is not a function of Mockk – Rn
@DouglasMesquita, agree, it is Mockito. – Ultramicrometer

© 2022 - 2024 β€” McMap. All rights reserved.