Justin Ramos
10/18/2021, 7:39 PM0.11.6
to 1.0.10
and ran into an issue and wanted to reach out to the community to see what you all recommend. Below is how we’ve been testing the default state of our viewmodels and we’ve never had issues.
class FeatureFlagViewModel(
private val featureFlagStorage: FeatureFlagStorage
) : AndroidDataFlow(defaultState = FeatureFlagScreenState(isButtonVisible = featureFlagStorage.getFeatureFlagState()!!)) {...}
class FeatureFlagViewModelTest : BaseCovaltoUnitTest() {
private val mockFeatureFlagStorage: FeatureFlagStorage = mockk(relaxed = true)
private lateinit var viewModel: FeatureFlagViewModel
private lateinit var view: TestViewObserver
@Before
fun setup() {
coEvery {
mockFeatureFlagStorage.getFeatureFlagState()
} returns true
viewModel = FeatureFlagViewModel(mockFeatureFlagStorage)
view = viewModel.createTestObserver()
}
@Test
fun `Should set feature flag states properly by default`() {
assertThat(view.lastStateOrNull)
.isEqualTo(
FeatureFlagScreenState(isCreateAccountButtonVisible = true)
)
}
When I run the tests after upgrading to the stable version it fails with the error in the photo below. The issue seems to be that the viewmodel is initialized before it can be observed so we never see the default state set. In other tests when we call viewModel.doStuff()
the viewmodel state is properly updated. An easy fix is to create the default state in the init method of the viewModel like this:
class FeatureFlagViewModel(
private val featureFlagStorage: FeatureFlagStorage
) : AndroidDataFlow() {
init {
action {
setState(FeatureFlagScreenState(isCreateAccountButtonVisible = featureFlagStorage.getFeatureFlagState()!!))
}
}
However, this feels a bit cumbersome to do in every viewmodel we have. It would be great to keep instantiating state the way we’re currently doing it. What do you guys recommend we do though?Erik
10/18/2021, 8:43 PMAndroidDataFlow
, but the factory that instantiates your data flow and the factory that instantiates the initial state.Justin Ramos
10/19/2021, 2:43 AMViewModel
which is unnecessary. That said there are other places where we use verifySequence()
in order to verify all changes to state and being able to do something like this feels reasonable.
tester.verifySequence(
MyState(value=0),
MyState(value=1),
MyState(value=2)
)
Having to convert our tests to the below is fine, but I feel like being able to observe a AndroidDataFlow
’s feels like something that should be doable…Especially because we were already able to do it 😅
tester.verifySequence(
MyState(value=1),
MyState(value=2)
)
Erik
10/19/2021, 7:07 AMJustin Ramos
10/19/2021, 2:27 PMinit {}
approach for any situations that truly needed to have their default state tested. Thanks for the help 🙂Erik
10/29/2021, 9:49 AMarnaud.giuliani
10/29/2021, 10:28 AM