You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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类的真实实现,适配单元测试场景:

  1. 在模块的build.gradle.kts(Groovy则用build.gradle)中添加依赖:
testImplementation("org.robolectric:robolectric:4.12.1")
  1. 若用JUnit4,在测试类上添加@RunWith(RobolectricTestRunner::class)注解;若用JUnit5,配置Robolectric扩展。
  2. 重新运行测试,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 21:17:46