gpt4 book ai didi

具有模拟和协程的 Android 测试存储库返回 NullPointerException

转载 作者:行者123 更新时间:2023-12-04 04:23:56 25 4
gpt4 key购买 nike

我有点困惑我应该如何测试它

我有这个存储库类:


class AuthenticationBox(
private val dataMapper: AuthenticationDataMapper,
private val dataSource: AuthenticationDataSource
) : BaseRepository<UserAuthentication>(), AuthenticationRepository {

override suspend fun fetchAuthenticationFromServer(
username: String,
password: String
): ResourceResult<UserAuthentication>? {
var result: ResourceResult<UserAuthentication>? = null

withContext(Dispatchers.IO) {
try {
val response = dataSource
.fetchAuthenticationFromServerAsync(username, password).await()

if (response.hasErrors()) {
result =
ResourceResult.Error(ApolloException(response.errors()[0].message()))

} else {
response.data()?.let {
val authorization = dataMapper.toDomain(it.loginResponse)

result = ResourceResult.Success(authorization)
}

}

} catch (error: ApolloException) {
result = handleAuthenticationError(error)
}
}
return result

}


}

这一行调用了一个返回 Deferred<Response> 的数据源方法对象并等待它 val response = dataSource.fetchAuthenticationFromServerAsync(username, password).await()

当我尝试测试它时,我总是得到一个 NullPointerException正好在这条线上
这是我的测试类:

class AuthenticationBoxTest {

lateinit var repository: AuthenticationRepository

var dataSourceMock: AuthenticationDataSource = mock()
var dataMapperMock: AuthenticationDataMapper = mock()


@Before
fun setup() {
repository = AuthenticationBox(
dataMapper = dataMapperMock,
dataSource = dataSourceMock
)
}

@Test
fun testFromServer() {
val username = "username"
val password = "password"
runBlocking {
repository.fetchAuthenticationFromServer(username, password)
}
}

}

日志输出为:

java.lang.NullPointerException
at br.com.ampli.authentication.repository.AuthenticationBox$fetchAuthenticationFromServer$2.invokeSuspend(AuthenticationBox.kt:45)
at |b|b|b(Coroutine boundary.|b(|b)
at br.com.ampli.authentication.repository.AuthenticationBox.fetchAuthenticationFromServer(AuthenticationBox.kt:42)
at br.com.ampli.authentication.repository.AuthenticationBoxTest$testFromServer$1.invokeSuspend(AuthenticationBoxTest.kt:126)
Caused by: java.lang.NullPointerException
at br.com.ampli.authentication.repository.AuthenticationBox$fetchAuthenticationFromServer$2.invokeSuspend(AuthenticationBox.kt:45)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:740)


我在这个存储库类上的所有其他功能都是暂停功能,并且都使用 withContext(Dispatchers.IO)并且我能够对它们进行全部测试(其中任何一个都称为另一个类)。这是唯一给我这个错误的。

在此先感谢您对此的任何见解。

最佳答案

您的 mock() 可能有错误。您确定数据源模拟有一个返回该方法的延迟的实现吗?

.fetchAuthenticationFromServerAsync(username, password)

This medium post有一个模拟方法返回延迟的示例,它会为您的用例提供类似这样的内容:

//a small helper function first
fun <T> T.toDeferred() = GlobalScope.async { this@toDeferred }

val authResult = dummyAuthDataSourceResult //dummy result
val mockedDatasource = mock<AuthenticationDataSource> {
on { fetchAuthenticationFromServerAsync() } doReturn authResult.toDeferred()
}

现在您应该可以安全地调用:

mockedDatasource.fetchAuthenticationFromServerAsync().await()

关于具有模拟和协程的 Android 测试存储库返回 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58328583/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com