Thanks for the question. It is possible to modify the data a ViewModel consumes or is initialized with. However, it largely depends on how you are creating your ViewModel.
Are you using any form of dependency injection with your ViewModels? How this is handled depends somewhat on how you create your ViewModels.
Are you using a mocking library such as mockito-android? This can greatly simplify the modification of data consumed by a ViewModel.
As a best practice, it is recommend to focus the Testify testing on the view-layer: the View, Compose, Fragment or Activity and the way that they render. When testing the view-layer, an entity such as the ViewModel can be considered to be external dependencies to your tests and so you can focus on coercing your views to render the state you desire through any means available. When it comes to ViewModels, a good strategy is to use a stub or mock of your ViewModel instead of a real instance. Then, you can set the ViewModel to return any values you desire.
Do you have an example of what you'd like to accomplish?
In my personal project, I accomplish this by first creating a custom subclass of ScreenshotRule. In this subclass, I override fun beforeAssertSame() and add a method setViewModelState.
With these, I can set up the ViewModel state prior to taking my screenshot. Here is a rough example of what this looks like:
class CustomScreenshotRule<TViewModel> : ScreenshotRule<ScreenshotTestActivity>() {
private var viewModelStateModifications: ((TViewModel) -> Unit)? = null
fun setViewModelState(viewModelStateModifications: (TViewModel) -> Unit): CustomScreenshotRule<TViewModel> {
this.viewModelStateModifications = viewModelStateModifications
return this
}
override fun beforeAssertSame() {
super.beforeAssertSame()
InstrumentationRegistry.getInstrumentation().runOnMainSync {
val extras = fragmentNavigation?.extras ?: viewModelExtras()
viewModelSpy.createViewModel(extras).let { viewModel ->
viewModelStateModifications?.let {
it(viewModelSpy.viewModel)
}
}
}
}
}
And then your test would look something like:
class MyTest {
val screenshotTestRule = CustomScreenshotRule<MyViewModel>()
@ScreenshotInstrumentation
@Test
fun default() {
screenshotTestRule
.setViewModelState { viewModel ->
doReturn(5).whenever(viewModel).sum()
}
.assertSame()
}
}
Hello @rdesai-handy
Thanks for the question. It is possible to modify the data a ViewModel consumes or is initialized with. However, it largely depends on how you are creating your ViewModel.
Are you using any form of dependency injection with your ViewModels? How this is handled depends somewhat on how you create your ViewModels.
Are you using a mocking library such as
mockito-android
? This can greatly simplify the modification of data consumed by a ViewModel.As a best practice, it is recommend to focus the Testify testing on the view-layer: the
View
,Compose
,Fragment
orActivity
and the way that they render. When testing the view-layer, an entity such as the ViewModel can be considered to be external dependencies to your tests and so you can focus on coercing your views to render the state you desire through any means available. When it comes to ViewModels, a good strategy is to use a stub or mock of your ViewModel instead of a real instance. Then, you can set the ViewModel to return any values you desire.Do you have an example of what you'd like to accomplish?
In my personal project, I accomplish this by first creating a custom subclass of
ScreenshotRule
. In this subclass, I overridefun beforeAssertSame()
and add a methodsetViewModelState
. With these, I can set up the ViewModel state prior to taking my screenshot. Here is a rough example of what this looks like:And then your test would look something like: