Issue
I'm currently writing some UI unit tests for a fragment, and one of these @Test
is to see if a list of objects is correctly displayed, this is not an integration test, therefore I wish to mock the ViewModel
.
The fragment's vars:
class FavoritesFragment : Fragment() {
private lateinit var adapter: FavoritesAdapter
private lateinit var viewModel: FavoritesViewModel
@Inject lateinit var viewModelFactory: FavoritesViewModelFactory
(...)
Here's the code:
@MediumTest
@RunWith(AndroidJUnit4::class)
class FavoritesFragmentTest {
@Rule @JvmField val activityRule = ActivityTestRule(TestFragmentActivity::class.java, true, true)
@Rule @JvmField val instantTaskExecutorRule = InstantTaskExecutorRule()
private val results = MutableLiveData<Resource<List<FavoriteView>>>()
private val viewModel = mock(FavoritesViewModel::class.java)
private lateinit var favoritesFragment: FavoritesFragment
@Before
fun setup() {
favoritesFragment = FavoritesFragment.newInstance()
activityRule.activity.addFragment(favoritesFragment)
`when`(viewModel.getFavourites()).thenReturn(results)
}
(...)
// This is the initial part of the test where I intend to push to the view
@Test
fun whenDataComesInItIsCorrectlyDisplayedOnTheList() {
val resultsList = TestFactoryFavoriteView.generateFavoriteViewList()
results.postValue(Resource.success(resultsList))
(...)
}
I was able to mock the ViewModel
but of course, that's not the same ViewModel
created inside the Fragment
.
So my question really, has someone done this successfully or has some pointers/references that might help me out?
Also, I've tried looking into the google-samples but with no luck.
For reference, the project can be found here: https://github.com/JoaquimLey/transport-eta/
Solution
In the example you provided, you are using mockito to return a mock for a specific instance of your view model, and not for every instance.
In order to make this work, you will have to have your fragment use the exact view model mock that you have created.
Most likely this would come from a store or a repository, so you could put your mock there? It really depends on how you setup the acquisition of the view model in your Fragments logic.
Recommendations: 1) Mock the data sources the view model is constructed from or 2) add a fragment.setViewModel() and Mark it as only for use in tests. This is a little ugly, but if you don't want to mock data sources, it is pretty easy this way.
Answered By - Sam Edwards
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.