如何在Robolectric测试中让Intent.resolveActivity()返回true?
我来帮你搞定这个Robolectric里模拟Intent.resolveActivity()返回true的问题!下面给你两种实用的解决方案,都是Robolectric测试里常用的手段:
在Robolectric中模拟Intent.resolveActivity()返回true的方案
方法一:用Robolectric原生ShadowPackageManager(推荐)
Robolectric的Shadow类专门用来模拟Android系统组件的行为,我们可以通过ShadowPackageManager给目标Intent绑定一个能处理它的Activity信息,这样resolveActivity()就会返回非null(对应业务代码里“解析成功”的判断逻辑)。
示例代码如下:
import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.Shadows; import org.robolectric.shadows.ShadowPackageManager; import android.content.Intent; import android.content.pm.ResolveInfo; @RunWith(RobolectricTestRunner.class) public class IntentResolveTest { @Test public void testIntentCanResolve() { // 1. 创建你要测试的目标Intent Intent testIntent = new Intent(Intent.ACTION_VIEW); testIntent.setData(android.net.Uri.parse("https://your-target-url.com")); // 2. 获取Robolectric的ShadowPackageManager实例 ShadowPackageManager shadowPackageManager = Shadows.shadowOf( RuntimeEnvironment.getApplication().getPackageManager() ); // 3. 模拟一个能处理该Intent的ResolveInfo ResolveInfo mockResolveInfo = new ResolveInfo(); mockResolveInfo.activityInfo = new android.content.pm.ActivityInfo(); mockResolveInfo.activityInfo.packageName = "com.your.app"; mockResolveInfo.activityInfo.name = "com.your.app.TestHandlerActivity"; // 4. 将模拟的ResolveInfo绑定到目标Intent上 shadowPackageManager.addResolveInfoForIntent(testIntent, mockResolveInfo); // 5. 现在测试你的业务代码,resolveActivity()会返回非null,即解析成功 assert testIntent.resolveActivity(RuntimeEnvironment.getApplication().getPackageManager()) != null; } }
核心逻辑就是通过addResolveInfoForIntent()给Intent注册一个有效的处理组件,让Robolectric的PackageManager认为这个Intent是可以被解析的。
方法二:结合Mockito mock PackageManager(灵活场景适用)
如果你的项目已经在用Mockito,也可以直接mock PackageManager的resolveActivity()方法,让它返回一个模拟的ComponentName:
import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import android.content.Intent; import android.content.pm.PackageManager; import android.content.ComponentName; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class IntentResolveWithMockitoTest { @Mock PackageManager mockPackageManager; @Test public void testIntentResolveSuccess() { Intent testIntent = new Intent(Intent.ACTION_SEND); testIntent.setType("text/plain"); // mock resolveActivity方法,返回一个有效的ComponentName when(mockPackageManager.resolveActivity(testIntent, PackageManager.MATCH_DEFAULT_ONLY)) .thenReturn(new ComponentName("com.your.app", "com.your.app.ShareActivity")); // 验证解析结果为true(非null即成功) boolean canResolve = testIntent.resolveActivity(mockPackageManager) != null; assert canResolve; } }
如果你的业务代码依赖Application的PackageManager,可以把mock的PackageManager注入到Robolectric的Application实例中,或者直接在测试逻辑里替换对应的引用。
小提醒
业务代码里通常是用resolveActivity() != null来判断Intent是否能被解析,所以模拟返回一个有效的ComponentName/ResolveInfo就等价于“返回true”的场景啦。
内容的提问来源于stack exchange,提问作者Abhay Sood
相关产品推荐
相关产品推荐

