gpt4 book ai didi

android - java.lang.IllegalStateException : Cancel call cannot happen without a maybeRun

转载 作者:行者123 更新时间:2023-12-03 13:25:44 24 4
gpt4 key购买 nike

我正在尝试测试一个简单的 ViewModelRobolectric .

这是我的ViewModel
GreetingsViewModel.kt

@FlowPreview
@ExperimentalCoroutinesApi
class GreetingsViewModel : ViewModel() {


private val greetingsChannel = ConflatedBroadcastChannel<String>()

/**
* Whenever greetingsChannel offers a value, prepend `Hello ` with it and return.
*/
val greetingsResponse = greetingsChannel.asFlow()
.flatMapLatest { name ->
flowOf("Helo $name")
}.asLiveData(viewModelScope.coroutineContext)

/**
* To get new greetings
*/
fun askGreetings(name: String) {
greetingsChannel.offer(name)
}
}

这是我的单元测试文件

GreetingsViewModelTest.kt

@FlowPreview
@ExperimentalCoroutinesApi
@RunWith(AndroidJUnit4::class)
class GreetingsViewModelTest2 {

@Test
fun greeting_askGreetings_getWithName() {
val testViewModel = GreetingsViewModel()
testViewModel.askGreetings("john")
testViewModel.greetingsResponse.getOrAwaitValue().should.equal("Hello john")
}
}

但是,当我运行测试时,我遇到了错误。

java.lang.IllegalStateException: Cancel call cannot happen without a maybeRun

at androidx.lifecycle.BlockRunner.cancel(CoroutineLiveData.kt:184)
at androidx.lifecycle.CoroutineLiveData.onInactive(CoroutineLiveData.kt:245)
at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:440)
at androidx.lifecycle.LiveData.observeForever(LiveData.java:232)
at com.theapache64.twinkill.test.GetOrAwaitValueKt.getOrAwaitValue(getOrAwaitValue.kt:26)
at com.theapache64.twinkill.test.GetOrAwaitValueKt.getOrAwaitValue$default(getOrAwaitValue.kt:15)
at com.theapache64.tracktor.ui.activities.test.GreetingsViewModelTest.greeting_askGreetings_getWithName(GreetingsViewModelTest.kt:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
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.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:546)
at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:252)
at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)


知道为什么吗?

注意: getOrAwaitValue()是获取 LiveData 值的扩展函数或等待它有一个,超时。

最佳答案

我面临着同样的问题。正如@Rahul Singhal 指出错误的原因是这一行

    this@getOrAwaitValue.removeObserver(this)

所以我决定将 LiveData 转换回流,然后获取值。这是我现在用来获取值(value)的扩展。
    suspend fun <T> LiveData<T>.getFlowAsLiveDataValue(timeMillis: Long = 2_000): T? =
withTimeoutOrNull(timeMillis) {
this@getFlowAsLiveDataValue.asFlow().first()
}

你的测试应该看起来像
    testViewModel.greetingsResponse.getFlowAsLiveDataValue().should.equal("Hello john")

关于android - java.lang.IllegalStateException : Cancel call cannot happen without a maybeRun,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61463006/

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