单元测试报错:Uri.EMPTY为空引发NullPointerException问题排查
问题:创建BaseItem实例时触发NullPointerException(EMPTY must not be null)
定义的实体类
data class BaseItem( val id: Long = 0, val name: String = "", val description: String = "", val uri: Uri = Uri.EMPTY, val active: Boolean = true, val done: Boolean = false, val date: LocalDate? = null, val plantId: Long = 0 )
待测试的ViewModel方法
fun getEmptyUiState(): Pair<BaseItem, List<BaseItem>> { return Pair(BaseItem(), listOf<BaseItem>()) }
测试代码
@Test fun getEmptyUiState() { val emptyUiState = viewModel.getEmptyUiState() assertThat(emptyUiState).isEqualTo(Pair(BaseItem(), listOf<BaseItem>())) }
报错信息
EMPTY must not be null java.lang.NullPointerException: EMPTY must not be null at com.rachapps.uielements.dto.BaseItem.(BaseItem.kt:11)
原因分析
Uri是Android框架提供的类,默认JUnit单元测试环境不会加载Android依赖,导致Uri.EMPTY这个静态常量未被初始化,处于null状态。创建BaseItem实例使用默认值时,就会触发空指针异常。
解决办法
1. 使用Robolectric运行测试
Robolectric可在本地模拟Android运行环境,让Uri.EMPTY正常初始化。JUnit4环境下只需在测试类添加@RunWith(RobolectricTestRunner::class)注解,JUnit5则需在构建配置中添加对应Robolectric依赖并配置测试规则。
2. 修改实体类默认值
将Uri类型改为可空,或用字符串替代默认值,避免直接依赖Android框架类的静态常量:
// 改为可空类型 val uri: Uri? = null // 或者用字符串存储,业务逻辑中再转换为Uri val uriString: String = ""
3. 手动初始化Uri.EMPTY(不推荐)
通过反射提前初始化Uri类的静态字段,但这种方式易出现兼容问题,维护成本高,优先推荐前两种方案。
内容的提问来源于stack exchange,提问作者RCH
相关产品推荐
相关产品推荐

