Hilt仪器测试绑定两个ViewModel报错问题求助
解决Hilt仪器测试中"The component was not created"错误
针对你遇到的问题,以下是具体的修复步骤:
1. 调整Rule执行顺序与Activity启动时机
ActivityScenarioRule在初始化时会直接启动Activity,但此时Hilt组件还未创建(hiltRule.inject()还没执行),导致依赖注入失败。需要改为在setup()方法中手动启动Activity:
@get:Rule(order = 0) var hiltRule = HiltAndroidRule(this) @get:Rule(order = 1) val setupRepoRule = SetupRepoRule(ApplicationProvider.getApplicationContext()) // 改为lateinit,避免提前初始化 private lateinit var activityScenario: ActivityScenario<TourActivity>
在setup()中启动Activity(必须在hiltRule.inject()之后):
@Before fun setup() { hiltRule.inject() activityScenario = ActivityScenario.launch(TourActivity.createIntent(context)) // 其他初始化逻辑... }
2. 修正Mock对象的初始化
@Mock注解需要配合Mockito初始化逻辑才能生效,在setup()开头添加:
MockitoAnnotations.openMocks(this)
或者添加MockitoRule简化配置:
@get:Rule(order = -1) val mockitoRule = MockitoJUnit.rule()
3. 修正@BindValue的ViewModel声明
@BindValue的属性需使用lateinit var,确保Hilt能正确识别并替换依赖,同时在setup()中完成ViewModel初始化:
@BindValue lateinit var viewModel: TourViewModel @BindValue lateinit var userInactivityViewModel: UserInactivityViewModel @Before fun setup() { MockitoAnnotations.openMocks(this) hiltRule.inject() viewModel = TourViewModel( userDataRepo = userDataRepo, scheduler = Schedulers.computation() ) userInactivityViewModel = UserInactivityViewModel( authTokenData = authTokenRepo, scheduler = Schedulers.computation(), tokenRepo = tokenRepo ) // 其他逻辑... }
4. 避免提前获取Context
不要在类属性初始化阶段直接获取Context,改为使用lazy延迟加载:
private val context: Context by lazy { ApplicationProvider.getApplicationContext() } private val targetContext: Context by lazy { InstrumentationRegistry.getInstrumentation().targetContext }
完整修复后的代码示例
@RunWith(AndroidJUnit4::class) @HiltAndroidTest class TourActivityUat { private val context: Context by lazy { ApplicationProvider.getApplicationContext() } private val targetContext: Context by lazy { InstrumentationRegistry.getInstrumentation().targetContext } @get:Rule(order = 0) var hiltRule = HiltAndroidRule(this) @get:Rule(order = 1) val mockitoRule = MockitoJUnit.rule() @get:Rule(order = 2) val setupRepoRule = SetupRepoRule(context) private lateinit var activityScenario: ActivityScenario<TourActivity> @Mock private lateinit var userDataRepo: UserDataRepo @Mock private lateinit var authTokenRepo: AuthTokenData private val tokenRepo by lazy { TokenRepository(cookieJar = ClearableCookieJarTest(context)) } @BindValue lateinit var viewModel: TourViewModel @BindValue lateinit var userInactivityViewModel: UserInactivityViewModel @Before fun setup() { hiltRule.inject() // 初始化ViewModel viewModel = TourViewModel( userDataRepo = userDataRepo, scheduler = Schedulers.computation() ) userInactivityViewModel = UserInactivityViewModel( authTokenData = authTokenRepo, scheduler = Schedulers.computation(), tokenRepo = tokenRepo ) // 启动Activity activityScenario = ActivityScenario.launch(TourActivity.createIntent(context)) // Mock数据 val notificationsResponse = NotificationResponse.test( messages = 4, documents = 0 ) whenever(userDataRepo.notifications).doReturn(Observable.just(notificationsResponse)) whenever(userDataRepo.relationshipIds).doReturn(Single.just(listOf(1L))) whenever(userDataRepo.fetchNotifications(any())).doReturn(Completable.complete()) whenever(userDataRepo.firstName).doReturn(Single.just("Kristy")) context.saveTourVisitedStatus(false) } // 测试方法... }
内容的提问来源于stack exchange,提问作者Kristy Welsh
相关产品推荐
相关产品推荐

