单元测试中无法执行/system/bin/ping命令的问题排查
解决方案
1. 核心原因:运行环境不匹配
这不是权限问题,而是本地JUnit测试的运行环境是电脑的JVM,而非Android设备:
/system/bin/ping是Android系统特有的ping工具路径,Windows/macOS/Linux等电脑系统里不存在这个路径(比如mac是/usr/bin/ping,Windows是ping.exe)。本地单元测试跑在电脑上,自然找不到这个文件。
2. 两种解决思路
(1)用仪器化测试跑真实ping逻辑
如果要验证真实的ping功能,把测试改成Android Instrumented Test:
- 测试类放在
androidTest目录下(而非test目录) - 运行时选择Android设备或模拟器,这样就能访问到Android系统的
/system/bin/ping,和你在设备上运行的环境完全一致。
(2)本地单元测试用Mock隔离系统依赖
如果只是要测试ping方法的逻辑(比如异常处理、结果转换),没必要真执行系统命令,用Mock框架(比如Mockito)把executePing方法的行为模拟出来:
// 先把executePing改成open方法,或者抽象成接口 open fun executePing(host: String): List<String> { // 原实现 } // 测试类中Mock这个方法 @ExperimentalCoroutinesApi class MCxCoreUtilitiesUnitTest { @Test fun `ping on localhost returns expected result`() = runTest { val mockCore = mock(MCxCoreUtilities::class.java) `when`(mockCore.executePing("127.0.0.1")).thenReturn(listOf("64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.123 ms")) `when`(mockCore.ping("127.0.0.1")).thenCallRealMethod() val result = mockCore.ping("127.0.0.1") assertTrue(result.matches(Regex(".*64 bytes from.*"))) } }
3. 额外修复:测试断言错误
原测试代码里的assertEquals(result, expectedOutputRegex)是错误的,应该用assertTrue(result.matches(expectedOutputRegex))来判断结果是否匹配正则表达式,而不是直接对比字符串和Regex对象。
内容的提问来源于stack exchange,提问作者Chris Pi
相关产品推荐
相关产品推荐

