将Toast替换为Snackbar后单元测试崩溃,寻求解决方案
解决Snackbar单元测试InflateException及Material库R无法解析问题
问题背景
已将项目中的Toast替换为Snackbar,添加了依赖:
implementation('com.google.android.material:material:1.8.0-alpha01')
Snackbar显示逻辑如下:
private fun showMessageInSnackbar (message: String) { val snackbar = view?.let { Snackbar.make(it, message, Snackbar.LENGTH_LONG) } }
真机和模拟器上运行正常,但执行包含该Fragment的单元测试时,触发如下报错:
android.view.InflateException: Binary XML file line #51 in com.xxxxxx.xxx:layout/design_layout_snackbar_include: Binary XML file line #51 in com.xxxxxx.xxx:layout/design_layout_snackbar_include: Error inflating class
同时存在两个额外现象:
- 单元测试并未针对Snackbar逻辑编写断言,仅执行Fragment初始化就触发报错
- Material库源码中
import com.google.android.material.R;的R符号显示红色,无法解析
解决方案
1. 补全测试环境的Material库依赖
单元测试环境默认不会自动继承主代码的implementation依赖,需在Module级别的build.gradle中添加测试依赖,版本要与主依赖一致:
testImplementation 'com.google.android.material:material:1.8.0-alpha01' androidTestImplementation 'com.google.android.material:material:1.8.0-alpha01'
2. 为测试指定Material主题
Snackbar依赖Material Design主题资源,单元测试中若使用默认空主题,会导致布局加载失败。在Fragment测试中指定Material主题:
@get:Rule val fragmentRule = FragmentScenarioRule.createInContainer(YourTargetFragment::class.java) { ContextThemeWrapper(it, R.style.Theme_MaterialComponents_DayNight) }
或者在测试所用的Activity配置中指定Material主题。
3. 修复Material库R无法解析问题
- 执行
Build > Clean Project,再执行Build > Rebuild Project,清理编译缓存 - 检查代码中R的导入:确保没有误导入
android.R,所有Material相关资源引用正确指向com.google.android.material.R - 若为Android Studio缓存问题,执行
File > Invalidate Caches... > Invalidate and Restart
4. 隔离测试:Mock Snackbar(可选)
如果测试无需验证Snackbar的真实显示效果,可通过Mockito拦截Snackbar的创建,避免触发真实布局加载:
@Mock lateinit var mockSnackbar: Snackbar @Before fun setup() { MockitoAnnotations.openMocks(this) whenever(Snackbar.make(any(View::class.java), anyString(), anyInt())).thenReturn(mockSnackbar) }
内容的提问来源于stack exchange,提问作者liliangeorg
相关产品推荐
相关产品推荐

