gpt4 book ai didi

android - 单元测试通过,但有错误

转载 作者:行者123 更新时间:2023-11-29 16:45:21 28 4
gpt4 key购买 nike

所以,我的一个单元测试有一个问题。它以绿灯完成,但是 ClassCastException 发生了。我要测试的类(class)如下所示:

@Singleton
class AuthManager @Inject constructor(val fireBaseAuth: FirebaseAuth) : AuthContract {

companion object {
const val SIGN_IN_SUCCEED = "SIGN_IN_SUCCEED"
const val UNKNOWN_ERROR = "UNKNOWN_ERROR"
}

override fun signIn(email: String, password: String): Single<Result> {
Timber.d("Email: $email, password: $password")
return Single.create({ emitter ->
fireBaseAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener {
if (it.isSuccessful) {
emitter.onSuccess(Result(isSucceed = true, code = SIGN_IN_SUCCEED))
Timber.d("Sign in by email and password succeed")
} else {
val exception = it.exception as FirebaseAuthException?
val result = handleSignInException(exception)
emitter.onSuccess(result)
Timber.d("Sign in by email and password returned error: " +
result.code)
}
}
})
}

private fun handleSignInException(exception: FirebaseAuthException?): Result {
if (exception == null) {
return Result(isSucceed = false, code = UNKNOWN_ERROR)
}
return Result(isSucceed = false, code = exception.errorCode)
}
}

我对单元测试的建议是这样的:

class AuthManagerTest {

@Mock
private lateinit var fireBaseAuth: FirebaseAuth

@Mock
private lateinit var authResult: Task<AuthResult>

private lateinit var authManager: AuthManager

private val EMAIL = "email@email.email"
private val PASSWORD = "password"

@Before
fun setupAuthManager() {
MockitoAnnotations.initMocks(this)
authManager = AuthManager(fireBaseAuth)
}

@Test
fun signInByEmailAndPasswordWithSuccessThenCheckIfResultSucceeds() {
whenever(authResult.isSuccessful).thenReturn(true)
whenever(fireBaseAuth.signInWithEmailAndPassword(EMAIL, PASSWORD)).thenReturn(authResult)
doAnswer{
val listener = it.arguments[0] as OnCompleteListener<AuthResult>
listener.onComplete(authResult)
}.`when`(authResult)
.addOnCompleteListener(ArgumentMatchers.any<OnCompleteListener<AuthResult>>())
val expectedResult = Result(isSucceed = true, code = AuthManager.SIGN_IN_SUCCEED)

val testObserver = authManager.signIn(EMAIL, PASSWORD)
.test()
testObserver.awaitTerminalEvent()

testObserver
.assertNoErrors()
.assertValue(expectedResult)
}
}

错误:

io.reactivex.exceptions.UndeliverableException: java.lang.ClassCastException: kotlin.Unit cannot be cast to com.google.android.gms.tasks.Task at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:366) at io.reactivex.internal.operators.single.SingleCreate$Emitter.onError(SingleCreate.java:97) at io.reactivex.internal.operators.single.SingleCreate.subscribeActual(SingleCreate.java:42) at io.reactivex.Single.subscribe(Single.java:2693) at io.reactivex.Single.test(Single.java:3104) at bla.bla.bla.AuthManagerTest.signInByEmailAndPasswordWithSuccessThenCheckIfResultSucceeds(AuthManagerTest.kt:48)

第 48 行是在 testObserver 上调用 test() 时。我不知道为什么会发生错误。

最佳答案

我们来看看MockitoAnswer接口(interface):

public interface Answer<T> {
/**
* @return the value to be returned
*/
T answer(InvocationOnMock invocation) throws Throwable;
}

如您所见,answer 方法返回对象

在您的代码中:

doAnswer{
val listener = it.arguments[0] as OnCompleteListener<AuthResult>
listener.onComplete(authResult)
}.`when`(authResult).addOnCompleteListener(ArgumentMatchers.any<OnCompleteListener<AuthResult>>())

answer 不返回任何内容,这在 Kotlin 中默认意味着返回 Unit

返回 Task,如 Task#addOnCompleteListener .写成:

doAnswer{
val listener = it.arguments[0] as OnCompleteListener<AuthResult>
listener.onComplete(authResult)
authResult
}.`when`(authResult).addOnCompleteListener(ArgumentMatchers.any<OnCompleteListener<AuthResult>>())

而且应该不错。

关于android - 单元测试通过,但有错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48667857/

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