Android Junit5搭配mannodermaus插件测试时Location返回null问题
问题根因
两个直接触发故障的核心问题点:
- 配置里开启的
unitTests.returnDefaultValues = true,会让纯JVM测试环境下所有Android SDK框架类的调用,不抛出“本地无该方法实现”的异常,而是直接返回默认空值——对象类型返回null,基本类型返回0。你调用的Location属于Android SDK框架类,纯JVM环境下根本没有具体实现,这么配置之后所有方法调用都是空操作。 - 切换到mannodermaus插件接JUnit5后,没有完成Robolectric与JUnit5的适配桥接,测试没有运行在Robolectric的Android模拟环境里。之前JUnit4用
@RunWith(RobolectricTestRunner.class)的方式,本质是启动测试时先加载Robolectric的类加载器,用Shadow类替换掉真实Android框架类的空实现,现在JUnit5下没有这套触发逻辑,自然拿不到有效的Location对象。 - 你写的build.gradle里还有语法错误:
testOptions块里嵌套了另一层testOptions,导致块内的所有配置根本没被Gradle识别生效,进一步加剧了环境混乱。
修复步骤
1. 替换适配JUnit5的Robolectric依赖
原来引入的Robolectric 4.3版本太旧,和JUnit5的适配性很差,直接替换为匹配的版本组合:
dependencies { // 原有其他依赖保持不变 testImplementation "org.robolectric:robolectric:4.10.3" testImplementation "org.robolectric:robolectric-junit:4.10.3" }
mannodermaus插件本身已经内置了Robolectric的支持逻辑,只要引入对应版本的依赖,测试运行时就会自动加载Shadow类,不需要额外写运行器注解。
2. 修正build.gradle中的无效配置
删掉多余嵌套的testOptions块,调整单测环境配置:
android { testOptions { // 关闭空返回逻辑,让Robolectric接管Android类的模拟 unitTests.returnDefaultValues = false unitTests.includeAndroidResources = true junitPlatform { filters { includeTags "slow" excludeTags "integration" } debugFilters { includeTags "integration" } } } // 其余原有android块配置保持不变 }
3. 测试类补充Robolectric标记
在测试类上加上mannodermaus提供的@RobolectricTest注解,代替原来JUnit4的运行器注解,明确告知测试运行器需要用Robolectric环境加载测试类,修正后的代码示例:
@RobolectricTest class LocationCheckTest { private fun strings(): Stream<String?>? { return Stream.of("foo", "bar") } @ParameterizedTest @MethodSource("strings") fun updateLocation(input: String) { val lat = 12.494831 val lon = 83.49899 val startLocation = Location("start") startLocation.latitude = lat startLocation.longitude = lon // 此时可以正常获取经纬度值,不会出现null返回 println("startLocation = $startLocation") } }
补充说明:如果调整后还是出现空返回,可以检查Robolectric版本与项目compileSdk版本的匹配关系,版本不匹配也会导致Shadow类加载失败,退回纯JVM的空实现逻辑。
内容的提问来源于stack exchange,提问作者Mahriban
相关产品推荐
相关产品推荐

