google/dagger

[Hilt] onCreate() in my Application doesn't called on Instrument test

Jaehwa-Noh opened this issue · 4 comments

My application class use @Inject and do some logic in onCreate() to add data in database.

• SearchFlightApplication.kt

@HiltAndroidApp
class SearchFlightApplication : Application() {
    @Inject
    lateinit var airportsRepository: AirportsRepository

    @Inject
    lateinit var airportsFtsRepository: AirportsFtsRepository

    @Inject
    @ApplicationScope
    lateinit var applicationScope: CoroutineScope

    override fun onCreate() {
        super.onCreate()
        applicationScope.launch {
            airportsFtsRepository.deleteAndInsertAll(
                airportsRepository.getAllAirportsEntities().map { airportEntity ->
                    airportEntity.asFtsEntity()
                }
            )
        }
    }
}

I made my own TestRunner as mentioned in hilt documentation.

• SearchFlightTestRunner.kt

class SearchFlightTestRunner : AndroidJUnitRunner() {
    override fun newApplication(
        cl: ClassLoader?,
        className: String?,
        context: Context?
    ): Application {
        return super.newApplication(cl, HiltTestApplication::class.java.getName(), context)
    }
}

The test is this.

• NavigationTest.kt

@HiltAndroidTest
class NavigationTest {
    @get:Rule(order = 0)
    val hiltRule = HiltAndroidRule(this)

    @get:Rule(order = 1)
    val composeTestRule = createAndroidComposeRule<MainActivity>()

    @Before
    fun setUp() = hiltRule.inject()

    @Test
    fun whenSearchHAM_ShowSuggestions() {
        composeTestRule.apply {
            onNodeWithContentDescription("Search").apply {
                performClick()
                performTextInput("HAM")
                performImeAction()
            }
            
            /**
             * There are two "HAM" on the screen.
             * One is in the search bar
             * Another is in the suggestions.
             */
            onAllNodesWithText("HAM").assertCountEquals(2)
        }
    }
}

But the test is failed because database is empty. It is by the onCreate() function in application not called.
What can I do to call onCreate() in Application to run the business logic?
Do I need a mock database?

You can see the project in my github

Hi, did you try adding logs to onCreate to verify onCreate was indeed not called? launch is an asynchronous call, so it may not get to run after the test finishes if you don't have some idling or blocking mechanism to make sure the launched task was executed.

Yes, I tested it with log and no onCreate called. I think we replaced the Application to HiltTestApplication. It seemed to bring this situation.

Right, @HiltAndroidTest will generate a test application for you. So @HiltAndroidApp one will be unused. I think @CustomTestApplication may help you

I just solve this application onCreate by implement in @Before function.

@Before
    fun setUp() {
        hiltRule.inject()
        runTest {
            airportsFtsRepository.deleteAndInsertAll(
                airportFtsEntitiesTestData
            )
        }
    }

Thank you to stay with me.