Fixed
Status Update
Comments
se...@google.com <se...@google.com> #2
I don't see if we can do anything about it. The only way not to break such ViewModel mocks is never ever add any code ViewModel class and it means that we can't add any features for it, for example we can't add viewModelScope for coroutines.
For now: if you want to mock your viewmodels, then do it in a way system doesn't about existence of this viewmodel's mock: don't return mocks from the viewmodel factory. Otherwise system will try to call methods (for example clear) and will fail.
Not sure how it should be exactly organised in your case, but generally: in real life you get a viewmodel from viewModelProvider, in test you don't call ViewModelProvider at all and use mock right-away.
For now: if you want to mock your viewmodels, then do it in a way system doesn't about existence of this viewmodel's mock: don't return mocks from the viewmodel factory. Otherwise system will try to call methods (for example clear) and will fail.
Not sure how it should be exactly organised in your case, but generally: in real life you get a viewmodel from viewModelProvider, in test you don't call ViewModelProvider at all and use mock right-away.
or...@gmail.com <or...@gmail.com> #3
I'm using Koin and creating mock view model like following
val mockSomeViewModel = mock<SomeViewModel>()
loadKoinModules(module {
viewModel(override = true) {
mockSomeViewModel
}
})
val mockSomeViewModel = mock<SomeViewModel>()
loadKoinModules(module {
viewModel(override = true) {
mockSomeViewModel
}
})
or...@gmail.com <or...@gmail.com> #4
I think this situation will be very common in cases where Fragment Testing library is being used for example i.e. where you want to test fragment in isolation and use a mocked ViewModel...in that case how would we set things up so that "system doesn't about existence of this viewmodel's mock"?
I also wasn't clear on following....and why mocking in general should prevent that...assuming there was way to mock out appropriate behaviour?
"The only way not to break such ViewModel mocks is never ever add any code ViewModel class and it means that we can't add any features for it"
I also wasn't clear on following....and why mocking in general should prevent that...assuming there was way to mock out appropriate behaviour?
"The only way not to break such ViewModel mocks is never ever add any code ViewModel class and it means that we can't add any features for it"
se...@google.com <se...@google.com> #5
mmm I see...
for now: I'd say the best I can suggest is to have a base abstract class SomeViewModel and in test class you'd have class PrepopulatedSomeViewModel and in the app you'd have something like FetchingSomeViewModel.
I'll think more and discuss it with the team, but currently I'm sceptical about if we have any good way around it.
for now: I'd say the best I can suggest is to have a base abstract class SomeViewModel and in test class you'd have class PrepopulatedSomeViewModel and in the app you'd have something like FetchingSomeViewModel.
I'll think more and discuss it with the team, but currently I'm sceptical about if we have any good way around it.
il...@google.com <il...@google.com> #7
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).
Description
Version used:1.1.0-alpha03
Devices/Android versions reproduced on:
as per
After updating to androidx.fragment:fragment-testing v1.0-alpha03 we're now getting following crash at end of test.
```
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)
```
Importantly this is test where we're mocking instance of ViewModel being used and issues seems to be related to associated changes to lifecycle-viewmodel v2.1.0-alpha01 which we now have a transitive dependency to. Specifically crash is occurring in following method because mBagOfTags is null
```
final void clear() {
mCleared = true;
for (Object value: mBagOfTags.values()) {
// see comment for the similar call in setTagIfAbsent
closeWithRuntimeException(value);
}
onCleared();
}
```
repo steps:
clone
checkout `fragment_test_issue ` branch
run `RouteListFragmentTest`