Skip to content

Make ViewModelComponent accessible via an EntryPoint #2925

Open
@realdadfish

Description

@realdadfish

Right now it is possible to create and access dependencies in UI tests via EntryPoints for pretty much every component. If one needs a dependency from ActivityRetainedComponent, an EntryPoint targeting ActivityComponent and FragmentComponent does the trick, because both components inherit the dependencies from ActivityRetainedComponent (and SingletonComponent, which however can be injected directly in the @HiltAndroidTest class).

Where this falls short is when one tries to access ViewModelComponent. Reason for this is because reference of the generated component in HiltViewModelFactory is never stored anywhere, so it becomes invisible to the outside world.

I understand that to let this work with the same mechanism like Fragments and Activitys, Hilt would have to generate a custom base instance of the ViewModel implementation and let this implement GeneratedComponentManager<ViewModelComponent>. Why hasn't this taken into consideration? Shouldn't the class that shares the lifetime with the component being able to hold an instance of it?

Right now, the only workaround is to make dependencies test-accessible in your ViewModel and let your test grab the original ViewModel instance from the factory:

@HiltViewModel
internal class MyViewModel @Inject constructor(
    @VisibleForTesting internal val stateHandle: SavedStateHandle
) : CustomBaseViewModel<Foo>() { ... }

// ...

private val viewModel: MyViewModel by lazy {
    var viewModel: MyViewModel? = null
    fragmentRule.fragmentScenario?.onFragment { fragment ->
        viewModel = ViewModelProvider(fragment)[MyViewModel::class.java]
    }
    requireNotNull(viewModel) { "Fragment is not yet initialized" }
}


@Test
fun myTest() {
    fragmentRule.launch()
    // do stubbing / verification
    viewModel.stateHandle.get(...)
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions