DroidT
DroidT

Reputation: 3293

Verify suspend function with Matchers.anyObject()

I'm attempting to add coroutines to our Android application but I'm hitting a snag with our mocking framework. My interface has a suspend function like so:

interface MyInterface {
  suspend fun makeNetworkCall(id: String?) : Response?
}

Here is how I'm attempting to verify the code was executed in my unit test

runBlocking {
  verify(myInterface).makeNetworkCall(Matchers.anyObject())
}

When I do this I'm getting the following error

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
2 matchers expected, 1 recorded:
-> at     com.myproject.MyTest$testFunction$1.invokeSuspend(MyTest.kt:66)

This exception may occur if matchers are combined with raw values:
  //incorrect:
  someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
  //correct:
  someMethod(anyObject(), eq("String by matcher"));

Is there another way we should verify that the appropriate method is being called when using coroutines? Any help would be appreciated.

Upvotes: 3

Views: 4085

Answers (1)

Natig Babayev
Natig Babayev

Reputation: 3296

I tried to write similar test using the code you have provided. Initially, I got same error as yours. However, when I used mockito-core v2.23.4, the tests were passed.

Here are quick steps which you can try:

  1. add testCompile "org.mockito:mockito-core:2.23.4" to the dependencies list in your build.gradle file.

  2. Run the tests again, and you should not get similar error.

As Matchers.anyObject() is deprecated, I used ArgumentMatchers.any().

Below you can see the client code:

data class Response(val message: String)

interface MyInterface {
    suspend fun makeNetworkCall(id: String?) : Response?
}

class Client(val  myInterface: MyInterface) {
    suspend fun doSomething(id: String?) {
        myInterface.makeNetworkCall(id)
    }
}

Here is the test code:

class ClientTest {
    var myInterface: MyInterface = mock(MyInterface::class.java)

    lateinit var SUT: Client

    @Before
    fun setUp() {
        SUT = Client(myInterface)
    }

    @Test
    fun doSomething() = runBlocking<Unit> {
        // Act
        SUT.doSomething("123")
        // Verify
        Mockito.verify(myInterface).makeNetworkCall(ArgumentMatchers.any())
    }
}

Upvotes: 3

Related Questions