Android测试Room TypeConverter时Uri.parse()未模拟报错求助
问题描述
我开发Android项目时,想用Room库存储资源URI,由于Room不支持复杂数据类型,我写了一个stringToUri类型转换器:
@TypeConverter fun stringToUri(string: String?): Uri? { return Uri.parse(string) }
为测试这个转换器,我写了如下测试函数:
@Test fun testStringToUri_validString_returnsUri() { val expectedUri = Uri.parse("content://media/external/audio/media/42") // 第165行 val actualUri = converter.stringToUri("content://media/external/audio/media/42") assertEquals(expectedUri, actualUri) }
但测试失败,报错:
Method parse in android.net.Uri not mocked.
java.lang.RuntimeException: Method parse in android.net.Uri not mocked.
at android.net.Uri.parse(Uri.java)
我是Android开发新手,这是第一个项目,希望解决这个错误。
解决办法
方法1:使用Robolectric框架
Robolectric能提供Android SDK类的真实实现,适配单元测试场景:
- 在模块的
build.gradle.kts(Groovy则用build.gradle)中添加依赖:
testImplementation("org.robolectric:robolectric:4.12.1")
- 若用JUnit4,在测试类上添加
@RunWith(RobolectricTestRunner::class)注解;若用JUnit5,配置Robolectric扩展。 - 重新运行测试,
Uri.parse会正常执行,生成真实Uri对象用于比较。
方法2:修改测试配置,允许未mock方法返回默认值
在模块的build.gradle.kts中添加配置,让Android SDK未mock的方法返回空值或默认对象(注意:生成的Uri对象仅能做简单相等性检查,不具备真实功能):
android { testOptions { unitTests { returnDefaultValues = true } } }
修改后重新运行测试,Uri.parse会返回mock对象,可通过assertEquals校验。
方法3:转换测试逻辑,不直接依赖Uri实现
转换器的核心是字符串与Uri的双向转换,可测试转换后的字符串一致性,避开对Uri.parse的依赖:
@Test fun testUriStringConversionRoundTrip() { val testUriString = "content://media/external/audio/media/42" val uri = converter.stringToUri(testUriString) val convertedBackString = converter.uriToString(uri) assertEquals(testUriString, convertedBackString) }
这种方式直接测试转换器的核心功能,简洁且可靠。
内容的提问来源于stack exchange,提问作者SONU
相关产品推荐
相关产品推荐

