So I'm trying to write a unit test for my Activity using Robolectric, however I have no idea how to provide a mocked viewmodel seeing as how my vm is instantiated directly in the class. This is due to the fact that jetpack's lifecycle aware ViewModel requires a Provider class to instantiate. So, I'm essentially injecting the custom provider and then using that to create my ViewModel. I've looked at other examples but they all seem extremely confusing. How do I achieve this?
class ActivityEpisodeList : AppCompatActivity() {
@Inject
lateinit var vmFactory: ViewModelProvider.Factory
private lateinit var vm: ActivityViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_episode_list)
MvvmDaggerApp.get(this).appComponent.inject(this)
vm = ViewModelProviders.of(this, vmFactory)[ActivityViewModel::class.java]
}
}
This is how I'm creating my ViewModel:
@Module
abstract class ViewModelModule {
@Binds
internal abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
@Binds
@IntoMap
@ViewModelKey(ActivityViewModel::class)
internal abstract fun postListViewModel(viewModel: ActivityViewModel): ViewModel
}
@Singleton
class ViewModelFactory @Inject constructor(private val viewModels: MutableMap<Class<out ViewModel>, Provider<ViewModel>>) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T = viewModels[modelClass]?.get() as T
}
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
@MapKey
internal annotation class ViewModelKey(val value: KClass<out ViewModel>)
You should inject a Test View Model from the module which appComponent is using to create dependencies here.
Do not create the viewmodel yourself. Create 2 modules for appComponent one which provides the original dependencies and other with test/mock dependencies. Something like this -
@Module
public AppModule {
public ViewModel appViewModel() { // return original here}
}
@Module
public TestAppModule extends AppModule {
public ViewModel appViewModel() { // return test/mock here}
}
In your test when you create Your AppComponent pass TestAppModule instead of AppModule, then you will get mocked dependencies.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With