I'm trying to wrap my head around Hilt and the way it deals with ViewModels. I would like my fragments to depend on abstract view models, so I can easily mock them during UI tests. Ex:
@AndroidEntryPoint
class MainFragment : Fragment() {
private val vm : AbsViewModel by viewModels()
/*
...
*/
}
@HiltViewModel
class MainViewModel(private val dependency: DependencyInterface) : AbsViewModel()
abstract class AbsViewModel : ViewModel()
Is there a way to configure by viewModels() so that it can map concrete implementations to abstract view models? Or pass a custom factory producer to viewModels() that can map concrete view models instances to abstract classes?
The exact question is also available here, but it is quite old considering hilt was still in alpha then: https://github.com/google/dagger/issues/1972 However, the solution provided there is not very desirable since it uses a string that points to the path of the concrete view model. I think this will not survive obfuscation or moving files and it can quickly become a nightmare to maintain. The answer also suggests injecting a concrete view model into the fragment during tests with all the view model's dependencies mocked, thus gaining the ability to control what happens in the test. This automatically makes my UI test depend on the implementation of said view model, which I would very much like to avoid.
Not being able to use abstract view models in my fragments makes me think I'm breaking the D in SOLID principles, which is something that I would also like to avoid.