mockito-kotlin: Matchers are not working for suspend functions

It seems that if you try to use “matchers” (any, eq, etc.) on suspend function mockito fails with “InvalidUseOfMatchersException”.

following test

@Test
fun otherTest() {
    val foo: Foo = mock {
        on { runBlocking { bar(any()) } } doReturn ("message")
    }
    Mockito.validateMockitoUsage()
}

with following interface definition

interface Foo {
    suspend fun bar(arg: String): String
}

produces following error

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
2 matchers expected, 1 recorded:
-> at org.app.Tests$otherTest$i$1$1$1.doResume(Tests.kt:76)

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 15
  • Comments: 19

Most upvoted comments

same problem as @lborisevich-clgx . high order functions doesn’t seem to work:

val myFunction = mock<suspend (Int) -> Boolean>()

myFunction.stub {
    onBlocking { invoke(any()) }.doReturn(false)
}
org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
2 matchers expected, 1 recorded:

but works with zero parameters:

val myFunction = mock<suspend () -> Boolean>()

myFunction.stub {
    onBlocking { invoke() }.doReturn(false)
}

I had to set my dependencies as below in my gradle file for the matchers to work within a suspend.

dependencies {
            testCompile 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.0.0'
            testCompile("org.mockito:mockito-core:2.23.0")
}

Is there an example of how to mock a suspend function on an existing mock object? All the examples I’ve seen set the mock up as it’s being instantiated. The constraint I’m working with is:

I have mock A built and given to me. Now, I need to mock a suspend API to return a value foo.

Example:

@Inject lateinit var mockA: A // using dagger to provide mocks configured in a separate module.

@Test
fun test1() = runBlocking {
    // how do i mock a suspend method on mockA?
}

@nhaarman looks like it’s back

This produces the same error:

mock<suspend (Int) -> Int> {
    onBlocking { invoke(any()) } doReturn 1
}

I am using: mockito-kotlin 2.2.0 mockito-core 3.6.28 kotlin 1.4.21

2.0.0-RC3 has just been released that supports non-experimental coroutines. Try again?