我在单元测试时得到了这个错误。
class com.example.model.common.shop.manager_cart.CartInfo cannot be cast to class kotlin.Result (com.example.model.common.shop.manager_cart.CartInfo and kotlin.Result are in unnamed module of loader 'app')
java.lang.ClassCastException: class com.example.model.common.shop.manager_cart.CartInfo cannot be cast to class kotlin.Result (com.example.model.common.shop.manager_cart.CartInfo and kotlin.Result are in unnamed module of loader 'app')
at com.example.store.ui.feature.result.CartUiUpdateManager.updateCartUi(CartUiSyncManager.kt:30)
at com.example.store.ui.feature.result.CartUiUpdateManager$updateCartUi$1.invokeSuspend(CartUiSyncManager.kt)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:234)
at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:166)
at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:431)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:420)
at kotlinx.coroutines.CancellableContinuationImpl.resumeUndispatched(CancellableContinuationImpl.kt:518)
at kotlinx.coroutines.EventLoopImplBase$DelayedResumeTask.run(EventLoop.common.kt:500)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at com.example.store.CartUiUpdateManagerTest.sending three requests must call onWarn, move request to tempRequestQueue, process and call onSuccess(CartUiUpdateManagerTest.kt:43)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at jdk.proxy1/jdk.proxy1.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
and `updateCartUi(CartUiSyncManager.kt:30)` is `val result = request.invoke()`
下面是CartUiUpdateManager类。
class CartUiUpdateManager {
private var lastRequestHashCode = 0
val requestQueue: MutableList<suspend () -> Result<CartInfo>> = mutableListOf()
val tempRequestQueue: MutableList<suspend () -> Result<CartInfo>> = mutableListOf()
private var isCalling = false
suspend fun updateCartUi(
newRequest: suspend () -> Result<CartInfo>,
onSuccess: suspend (CartInfo) -> Unit,
onFailure: suspend (Throwable) -> Unit,
onWarn: suspend (String) -> Unit
) {
if (requestQueue.size == MAX_REQUEST) {
onWarn.invoke("Too many requests. Please wait.")
tempRequestQueue.add(newRequest)
return
}
requestQueue.add(newRequest)
while (requestQueue.isNotEmpty()) {
isCalling = true
val request = requestQueue.removeFirst()
lastRequestHashCode = newRequest.hashCode()
delay(DELAY_BETWEEN_API)
val response: Result<CartInfo> = request.invoke()
response.onSuccess {
if (tempRequestQueue.isNotEmpty()) {
requestQueue.add(tempRequestQueue.removeFirst())
requestQueue.add(tempRequestQueue.removeFirst())
} else if (requestQueue.isEmpty() && lastRequestHashCode == newRequest.hashCode()) {
isCalling = false
onSuccess.invoke(it)
}
}.onFailure {
if (requestQueue.isEmpty() && tempRequestQueue.isEmpty()) {
isCalling = false
}
onFailure.invoke(it)
}
}
}
companion object {
const val MAX_REQUEST = 2
const val DELAY_BETWEEN_API = 70L
}
}
下面是我的单元测试代码。
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.mockk
import com.example.model.common.shop.manager_cart.CartInfo
import com.example.store.ui.feature.result.CartUiUpdateManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import org.junit.After
import org.junit.Assert
import org.junit.Before
import org.junit.Rule
import org.junit.Test
class CartUiUpdateManagerTest {
@get:Rule
var instantExecutorRule = InstantTaskExecutorRule()
private lateinit var cartUiUpdateManager: CartUiUpdateManager
@Before
fun setUp() {
Dispatchers.setMain(Dispatchers.Unconfined)
cartUiUpdateManager = CartUiUpdateManager()
}
@After
fun tearDown() {
Dispatchers.resetMain()
}
@Test
fun `sending less than 3 request calls must call onSuccess`() = runTest {
val mockRequest = mockk<suspend () -> Result<CartInfo>>()
val cartInfo = mockk<CartInfo>(relaxed = true)
coEvery { mockRequest() } returns Result.success(cartInfo)
val onSuccess = mockk<suspend (CartInfo) -> Unit>(relaxed = true)
val onFailure = mockk<suspend (Throwable) -> Unit>(relaxed = true)
val onWarn = mockk<suspend (String) -> Unit>(relaxed = true)
cartUiUpdateManager.updateCartUi(
newRequest = mockRequest,
onSuccess = onSuccess,
onFailure = onFailure,
onWarn = onWarn
)
cartUiUpdateManager.updateCartUi(
newRequest = mockRequest,
onSuccess = onSuccess,
onFailure = onFailure,
onWarn = onWarn
)
coVerify(exactly = 2) { onSuccess(cartInfo) }
coVerify(exactly = 0) { onFailure(any()) }
coVerify(exactly = 0) { onWarn(any()) }
}
@Test
fun `sending three requests must call onWarn, move request to tempRequestQueue, process and call onSuccess`() = runBlocking {
val mockRequest = mockk<suspend () -> Result<CartInfo>>()
val cartInfo = mockk<CartInfo>(relaxed = true)
val successResult = Result.success(cartInfo)
coEvery { mockRequest() } returns successResult
val onSuccess = mockk<suspend (CartInfo) -> Unit>(relaxed = true)
val onFailure = mockk<suspend (Throwable) -> Unit>(relaxed = true)
val onWarn = mockk<suspend (String) -> Unit>(relaxed = true)
cartUiUpdateManager.updateCartUi(
newRequest = mockRequest,
onSuccess = onSuccess,
onFailure = onFailure,
onWarn = onWarn
)
cartUiUpdateManager.updateCartUi(
newRequest = mockRequest,
onSuccess = onSuccess,
onFailure = onFailure,
onWarn = onWarn
)
cartUiUpdateManager.updateCartUi(
newRequest = mockRequest,
onSuccess = onSuccess,
onFailure = onFailure,
onWarn = onWarn
)
coVerify(exactly = 1) { onWarn("Too many requests. Please wait.") }
Assert.assertEquals(1, cartUiUpdateManager.tempRequestQueue.size)
// Simulate the first two requests being processed successfully
cartUiUpdateManager.requestQueue.clear()
cartUiUpdateManager.tempRequestQueue.removeFirst()
coVerify(exactly = 3) { onSuccess(cartInfo) }
coVerify(exactly = 0) { onFailure(any()) }
}
}
有问题的部分是val response: Result<CartInfo> = request.invoke()
。我不知道为什么它需要铸造。
我如何调试和修复这个问题,使这些单元测试工作正常?
1条答案
按热度按时间hiz5n14c1#
堆栈跟踪告诉你错误在第30行:
你给我们看的代码中没有行号,但我想是这个:
request.invoke()
返回的是CartInfo
,但您需要的是Result
。