Compose中HiltViewModel测试时无法创建实例问题排查
问题描述
在Android上运行仪器化测试时,App本身运行正常,注释掉AskViewModel的test依赖后测试也能正常执行,但保留依赖时出现Cannot create an instance of class AskViewModel错误。不想直接在AskScreen Composable中注入依赖,怀疑问题出在createComposeRule()上。
相关代码如下:
测试类代码:
@HiltAndroidTest class AskScreenTest { @get:Rule(order = 0) val hiltRule = HiltAndroidRule(this) @get:Rule(order = 1) val composeRule = createComposeRule() @Before fun setup() { hiltRule.inject() composeRule.setContent { AskScreen() } } @Test fun openApp() { println("HELLO") } }
ViewModel代码:
@HiltViewModel class AskViewModel @Inject constructor( private val test: PostQuestion, ): ViewModel() { }
依赖类代码:
class PostQuestion @Inject constructor() { operator fun invoke() = Unit }
测试Module代码:
@Module @TestInstallIn( components = [SingletonComponent::class], replaces = [RepositoryModule::class] ) object RepositoryModuleTest { ... @Provides @Singleton fun providePostQuestion(): PostQuestion = PostQuestion() }
Composable代码:
@Composable fun AskScreen( modifier: Modifier = Modifier, ) { val viewModel: AskViewModel = hiltViewModel() }
解决方法
问题核心是普通Compose测试规则未关联Hilt依赖容器,导致hiltViewModel()无法获取所需依赖,以下是修复步骤:
- 替换Compose测试规则
把createComposeRule()换成Hilt适配的测试规则createAndroidComposeRule<HiltTestActivity>(),它会启动Hilt托管的测试Activity,让Composable在正确的依赖环境中运行:
@HiltAndroidTest class AskScreenTest { @get:Rule(order = 0) val hiltRule = HiltAndroidRule(this) @get:Rule(order = 1) val composeRule = createAndroidComposeRule<HiltTestActivity>() @Before fun setup() { hiltRule.inject() composeRule.setContent { AskScreen() } } @Test fun openApp() { println("HELLO") } }
- 确认依赖配置
确保Module级build.gradle中包含Hilt测试相关依赖(版本可根据项目实际调整):
androidTestImplementation "com.google.dagger:hilt-android-testing:2.48" kaptAndroidTest "com.google.dagger:hilt-android-compiler:2.48" androidTestImplementation "androidx.hilt:hilt-navigation-compose-testing:1.2.0"
- 验证测试Module有效性
确认RepositoryModuleTest的@TestInstallIn注解中,replaces参数指向生产环境提供PostQuestion的Module,且@Provides方法的作用域和返回值配置正确。
原理说明
普通的createComposeRule()没有绑定Hilt的依赖注入上下文,调用hiltViewModel()时无法找到ViewModel构造函数所需的PostQuestion实例。而createAndroidComposeRule<HiltTestActivity>()会初始化Hilt的依赖容器,让Composable能正常获取ViewModel及其依赖。
内容的提问来源于stack exchange,提问作者D-I-S-C
相关产品推荐
相关产品推荐

