如何Mock try-catch块内的startActivity()?解决测试失败问题
问题根源
你mock的Intent对象完全没被用到,rateUs方法里是直接创建新的Intent实例,这个mock无效;同时没有正确配置PackageManager的mock,导致调用startActivity(marketIntent)时可能抛出ActivityNotFoundException,进入catch块调用网页版Intent,最终捕获的不是预期的market链接Intent。
修改后的测试用例
@Test fun rateUs_LaunchGooglePlayStore() { // 初始化必要的mock对象 val activity = mock(FragmentActivity::class.java) val packageManager = mock(PackageManager::class.java) val packageName = "com.example.myapp" val expectedMarketUri = Uri.parse("market://details?id=$packageName") // 配置mock行为 `when`(activity.packageName).thenReturn(packageName) `when`(activity.packageManager).thenReturn(packageManager) // 让market链接的Intent能被正常解析,避免抛出异常进入catch块 `when`(packageManager.resolveActivity(any(Intent::class.java), anyInt())) .thenReturn(ComponentName(packageName, "com.android.vending")) // 忽略startActivity的实际执行逻辑 doNothing().`when`(activity).startActivity(any(Intent::class.java)) // 调用目标方法 ViewUtils.rateUs(activity) // 验证调用行为 val intentCaptor = argumentCaptor<Intent>() verify(activity).startActivity(intentCaptor.capture()) val capturedIntent = intentCaptor.firstValue assertNotNull(capturedIntent) assertEquals(Intent.ACTION_VIEW, capturedIntent.action) assertEquals(expectedMarketUri, capturedIntent.data) }
关键修改点
- 移除无用的
Intent和Urimock对象,rateUs方法会自行创建真实实例 - mock
PackageManager并配置resolveActivity返回有效组件,确保不会触发catch分支 - 用
anyInt()匹配resolveActivity的flag参数,贴合真实调用逻辑
如果需要更精确的匹配(确保只有market链接的Intent被解析成功),可以把resolveActivity的参数匹配替换为:
`when`(packageManager.resolveActivity(argThat { action == Intent.ACTION_VIEW && data == expectedMarketUri }, anyInt())).thenReturn(ComponentName(packageName, "com.android.vending"))
内容的提问来源于stack exchange,提问作者Hafizur Rahman
相关产品推荐
相关产品推荐

