首页 > 解决方案 > 存根方法时获取 InvalidUseOfMatchersException

问题描述

我在我的 Android 项目中使用 mockito 来测试将 a 转换QuerySnapshotList<Entry>.

这是我要测试的功能:

class EntriesMapper {

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

这是测试类:

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

这是一个例外:

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

我知道这是一个非常常见的异常,当您将匹配器与原始值结合使用时,您会看到我没有传入原始值。

标签: androidfirebasekotlinmockito

解决方案


我决定模拟 QuerySnapshot 的原因是它的构造函数是私有的,并且使用 mockito 存根 map 函数最终会带来比解决方案更多的问题。

QuerySnapshot 继承自 Iterable,因此我建议不要使用模拟,而是使用列表。

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

测试班

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

推荐阅读