简体   繁体   中英

Getting an InvalidUseOfMatchersException when stubbing method

I'm using mockito in my Android project to test that a function that converts a QuerySnapshot to a List<Entry> .

This is the function that I'm trying to test:

class EntriesMapper {

    fun map(querySnapshot: QuerySnapshot): List<Entry> {
        return querySnapshot.map { documentSnapshot ->
            Entry(documentSnapshot["id"] as String)
        }
    }
}

This is the test class:

class EntriesMapperTest {
    @Test
    fun `map should convert query snapshot to entry`() {
        val id = 1
        val documentSnapshot = mock<DocumentSnapshot> {
            on { this.id } doReturn id
        }
        val querySnapshot = mock<QuerySnapshot>()
        val transform = any<(DocumentSnapshot) -> Entry>()
        whenever(querySnapshot.map(transform)).thenAnswer { answer ->
            (answer.arguments.first() as (DocumentSnapshot) -> Entry).invoke(documentSnapshot)
        }
        val testObject = EntriesMapper()

        val entries = testObject.map(querySnapshot)
        val entry = entries.first()

        assertThat(entry.id, equalTo(id))
    }
}

And this is the exception:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
0 matchers expected, 1 recorded:
-> at io.company.myapp.entries.EntriesMapperTest.map should convert query snapshot to entry(EntriesMapperTest.kt:147)

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"));

I'm aware this is a very common exception you get when you combine matchers with raw values but as you can see I'm not passing in raw values.

The reason why I decided to mock out QuerySnapshot is that its constructor is private and stubbing out the map function with mockito ended up giving more problems than solutions.

QuerySnapshot inherits from Iterable so instead of using a mock I would recommend using a List.

class EntriesMapper {
    fun map(querySnapshot: Iterable<DocumentSnapshot>): List<Entry> {
        return querySnapshot.map { documentSnapshot ->
            Entry(documentSnapshot["id"] as String)
    }
}

Test class

class EntriesMapperTest {
    @Test
    fun `map should convert query snapshot to entry`() {
        val id = 1
        val documentSnapshot = mock<DocumentSnapshot> {
            on { this.id } doReturn id
        }
        val testObject = EntriesMapper()

        val entries = testObject.map(listOf(documentSnapshot))
        val entry = entries.first()

        assertThat(entry.id, equalTo(id))
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM