2

I am trying to mock a view model in my UI Tests. It seems like I don't have it set up correctly, because the VM in the test activity is "not initialized".

This is what I got:

  1. Hilt Module that provides my VM:
@Module
@InstallIn(SingletonComponent::class)
object ApplicationModule {
    @Provides
    fun provideMainViewModel(sharedPreferences: SharedPreferences): MainViewModel = MainViewModel(sharedPreferences)
}

  1. Test Module to provide mocks:
@Module
@TestInstallIn(
    components = [SingletonComponent::class],
    replaces = [ApplicationModule::class]
)
object MockModule {
    @Provides
    fun provideMainViewModel(): MainViewModel = mockk(relaxed = true)
}
  1. In my UI test:
@HiltAndroidTest
class ExampleInstrumentedTest {
    @Inject
    lateinit var viewModel: MainViewModel

    @get:Rule(order = 0)
    var hiltRule = HiltAndroidRule(this)

    @get:Rule(order = 1)
    val instantTaskExecutorRule = InstantTaskExecutorRule()

    private val showError = MutableLiveData<String>()

    @Before
    fun init() {
        hiltRule.inject()
        Intents.init()
        every { viewModel.showError } returns showError
    }

    @After
    fun cleanUp() {
        Intents.release()
        unmockkAll()
    }

    @Test
    fun testThis() {
        val activityScenario: ActivityScenario<MainActivity> = ActivityScenario.launch(MainActivity::class.java)
    }

However, when I run the test, the view model is not a mock! What am I missing?

lisa
  • 640
  • 5
  • 10
  • 26
  • 1
    I dont know Hilt, but I guess it does not work, because you init your Mock outside of your Test. Also when you want to Mock a MainViewModel relaxed you should do it like this: val mock = mockk(relaxed = true) – mjd Apr 22 '21 at 15:10

1 Answers1

0

Hilt only injects its objects (inside a test) after you call hiltRule.inject(), but you're trying to access viewModel before that, and that's why viewModel isn't initialized. Try putting hiltRule.inject() as the first line inside init:

@Before
fun init() {
    hiltRule.inject()
    every { viewModel.showError } returns showError
    Intents.init()
}
cd1
  • 15,908
  • 12
  • 46
  • 47