更新到 Fragment Testing 库 v1.1.0-alpha03 后崩溃
Crash after updating to Fragment Testing library v1.1.0-alpha03
更新到 androidx.fragment:fragment-testing
v1.0-alpha03 后,我们现在在测试结束时遇到以下崩溃。
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.Collection java.util.concurrent.ConcurrentHashMap.values()' on a null object reference
at androidx.lifecycle.ViewModel.clear(ViewModel.java:125)
at androidx.lifecycle.ViewModelStore.clear(ViewModelStore.java:62)
重要的是,这是我们模拟正在使用的 ViewModel
实例的测试,问题似乎与 lifecycle-viewmodel
v2.1.0-alpha01 的相关更改有关,我们现在有一个传递依赖到。具体来说,崩溃发生在以下方法中,因为 mBagOfTags
为 null
final void clear() {
mCleared = true;
for (Object value: mBagOfTags.values()) {
// see comment for the similar call in setTagIfAbsent
closeWithRuntimeException(value);
}
onCleared();
}
解决了这个问题,现在的标题可能有点误导。自 2.1.0-alpha01 更新
以来,问题似乎通常与模拟 ViewModel
实例有关
因此,如前所述,问题归结为自至少 v2.1.0-alpha01
发布以来无法模拟 ViewModel
个实例。事实证明,解决方案是使用 spy()
代替。我正在使用 Koin
,所以这意味着我的测试现在扩展了 KoinTest
。然后我可以将以下内容添加到 test
val someViewModel: SomeViewModel by inject()
然后调用下面
val spySomeViewModel = spy(someViewModel)
loadKoinModules(module {
viewModel(override = true) {
spySomeViewModel
}
})
然后,就像使用 mock()
时的情况一样,可以做类似
的事情
doReturn(someResult).whenever(spySomeViewModel).someMethod()
更新:
来自 https://issuetracker.google.com/issues/122273087
"We've fixed this internally in https://android-review.googlesource.com/863029 to ensure that mocked ViewModels work as before and this will be available in the next version of ViewModel (and Fragment, etc. that relies on it)."
更新到 androidx.fragment:fragment-testing
v1.0-alpha03 后,我们现在在测试结束时遇到以下崩溃。
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.Collection java.util.concurrent.ConcurrentHashMap.values()' on a null object reference
at androidx.lifecycle.ViewModel.clear(ViewModel.java:125)
at androidx.lifecycle.ViewModelStore.clear(ViewModelStore.java:62)
重要的是,这是我们模拟正在使用的 ViewModel
实例的测试,问题似乎与 lifecycle-viewmodel
v2.1.0-alpha01 的相关更改有关,我们现在有一个传递依赖到。具体来说,崩溃发生在以下方法中,因为 mBagOfTags
为 null
final void clear() {
mCleared = true;
for (Object value: mBagOfTags.values()) {
// see comment for the similar call in setTagIfAbsent
closeWithRuntimeException(value);
}
onCleared();
}
解决了这个问题,现在的标题可能有点误导。自 2.1.0-alpha01 更新
以来,问题似乎通常与模拟ViewModel
实例有关
因此,如前所述,问题归结为自至少 v2.1.0-alpha01
发布以来无法模拟 ViewModel
个实例。事实证明,解决方案是使用 spy()
代替。我正在使用 Koin
,所以这意味着我的测试现在扩展了 KoinTest
。然后我可以将以下内容添加到 test
val someViewModel: SomeViewModel by inject()
然后调用下面
val spySomeViewModel = spy(someViewModel)
loadKoinModules(module {
viewModel(override = true) {
spySomeViewModel
}
})
然后,就像使用 mock()
时的情况一样,可以做类似
doReturn(someResult).whenever(spySomeViewModel).someMethod()
更新: 来自 https://issuetracker.google.com/issues/122273087 "We've fixed this internally in https://android-review.googlesource.com/863029 to ensure that mocked ViewModels work as before and this will be available in the next version of ViewModel (and Fragment, etc. that relies on it)."