Intro
Testing user interfaces (UI) is a crucial aspect of software development, as it ensures the quality, stability, and overall user experience of an application. One effective approach to UI testing is to mock the ViewModel, which allows for a high degree of isolation and control over the tested components. This method focuses on verifying the UI’s behavior and its adaptation to different states, while removing dependencies on the actual backend implementation.
By mocking the ViewModel, UI tests can be more targeted and reliable, as they simulate various ViewModel states and responses without the need for a live backend connection. This approach eliminates potential sources of unexpected errors and inconsistencies that might arise from backend issues or network fluctuations. Consequently, UI tests can be executed faster and in a more controlled environment, leading to more efficient development cycles and improved application quality.
In contrast, end-to-end (E2E) tests involve the entire application stack, including the backend implementation. While E2E tests are essential for validating the overall functionality and integration of components, they can introduce complexities and uncertainties that make isolating and identifying issues more challenging. Moreover, E2E tests tend to be slower and more resource-intensive, which can impact development velocity.
TL/DR
By injecting ViewModelProvider.Factory in our UI components: Activities and Fragments, we can provide different implementation of ViewModel for production and for tests. This is easily achievable with using Hilt DI which can inject ViewModelProvider.Factory in ActivityRetainedComponent (both Activity and Fragment). Also, by using @TestInstallIn we can easily change and mock ViewModelProvider.Factory and provide fake ViewModel implementation in androidTest setup.
ViewModel setup
First, create Abstract ViewModel in order to encapsulate data and expose api to UI components (Activities and Fragments).