当被测试 class 而不是直接调用时,Mockito 的 `thenReturn` returns `null` 而不是 Pair(null."text")

Mockito's `thenReturn` returns `null` instead of Pair(null."text") when called by tested class and not directly

这里是测试和 Mockito 初学者,所以我希望这只是一些简单的错误。
编辑这很可能是因为函数是 suspend 函数

我的测试崩溃是因为 Mockito returns null 它应该 return 不可为空 Pair。在实时环境中,此代码运行良好(无 NPE),但我无法使用 Mockito 通过测试。
麻烦的模拟:

val mks = mock(MyKeyStore::class.java)
`when`(mks.createKeyStore(user,pass)).thenReturn(Pair(null, "userExists"))

MyKeyStore.createKeyStore() returns 不可为空 Pair

suspend fun createKeyStore(user: String, ksPass: String): Pair<KeyStore?, String>

mks.createKeyStore()UserRepo.createUser()
调用 UserRepo 崩溃是因为测试考虑了 ksResult == null,根据定义,它是不可空的。当我将其更改为可为空时,代码根本无法编译,所以我认为这与 Mockito 设置有关。

class UserRepo(private val myKeyStore: MyKeyStore) {
    suspend fun createUser(user: String, p0: String, p1: String): Pair<Boolean, String> =
        withContext(Dispatchers.IO) {
            return@withContext if (p0 == p1) {
                val ksResult = myKeyStore.createKeyStore(user, p0)
                ksResult.first?.let { //line where NPE crash leads
                    val keyResult = myKeyStore.createKeyDB(user, p0)
                    keyResult.first?.let { Pair(true, keyResult.second) } ?: run { Pair(false, keyResult.second) }
                } ?: run { Pair(false, ksResult.second) }
            } else Pair(false, myKeyStore.mPasswordsNotMatching)
        }
}

全面测试

    @Test
    fun createUserFailDueToUserExisting() = runBlocking() {
        val user = "user"
        val pass = "pass"
        val mks = mock(MyKeyStore::class.java)
        `when`(mks.createKeyStore(user,pass)).thenReturn(Pair(null, "userExists"))
        println(mks.createKeyStore(user,pass)) // this actually prints the pair correctly
        val repo = UserRepo(mks)
        val result = repo.createUser(user,pass,pass) // NPE crash, but why?
        assertFalse(result.first)
        assertTrue(result.second == "userExists")
    }

如何将模拟配置为 return Pair 而不是 null

因为函数是 suspend 函数,在 runBlocking 中指定调度程序为我修复了它
我在哪里找到答案:testing coroutines in Android

    @Test
    fun createUserFailDueToUserExisting() = runBlocking(Dispatchers.IO) {
        val user = "user"
        val pass = "pass"
        val mks = mock(MyKeyStore::class.java)
        `when`(mks.createKeyStore(user, pass)).thenReturn(Pair(null, "userExists"))
        println(mks.createKeyStore(user, pass))
        val repo = UserRepo(mks)
        val result = repo.createUser(user, pass, pass)
        assertFalse(result.first)
        assertTrue(result.second == "userExists")
    }