Android Studio用Robolectric测试Activity时Bundle为空,是否测试时机过早?
问题根因
直接调用Robolectric.setupActivity(LoginActivity.class)启动Activity时,Robolectric会生成无Extra数据的默认Intent启动目标Activity,读取到的Bundle自然为空,和前序Activity栈、数据填充时机无关,属于测试启动参数配置缺失问题。
如果你的测试放在androidTest目录运行在真机上,本质是Instrumented测试,更不需要依赖Robolectric的启动方法,直接用AndroidX Test提供的API即可。
修复方案
- 手动构造携带所需数据的Intent,包含你需要的Bundle和Parcelable对象,再用这个自定义Intent启动LoginActivity,不要使用默认无参的启动方法。
- Robolectric 4.x已废弃
Robolectric.setupActivity方法,推荐使用官方兼容的ActivityScenario实现Activity启动,写法更规范,也支持自定义Intent参数。
修改后的代码示例
@RunWith(RobolectricTestRunner.class) public class LoginActivityTest { LoginActivity activity; REdittext email; REdittext password; TextView signin; String e; String p; Bundle bundle; Info info; @Before public void setUp() { // 构造测试需要的测试数据 info = new Info(); info.bRemember = false; info.helpWSURL = Common.HELP_WS_URL; bundle = new Bundle(); bundle.putParcelable("Info", info); // 构造携带Bundle的目标Intent Intent intent = new Intent(ApplicationProvider.getApplicationContext(), LoginActivity.class); intent.putExtras(bundle); // 用自定义Intent启动Activity try(ActivityScenario<LoginActivity> scenario = ActivityScenario.launch(intent)) { scenario.onActivity(act -> { activity = act; // 初始化控件引用 email = activity.findViewById(R.id.rtxtEmail); password = activity.findViewById(R.id.rtxtPassword); signin = activity.findViewById(R.id.lblSignIn); }); } } @Test public void test_LoginActivity_ShouldNotBeNull() { assertNotNull(activity); } @Test public void test_IncomingBundleInfo_NotNull() { Bundle receivedBundle = activity.getIntent().getExtras(); assertNotNull(receivedBundle); Info receivedInfo = receivedBundle.getParcelable("Info"); assertNotNull(receivedInfo); assertEquals(Common.HELP_WS_URL, receivedInfo.helpWSURL); } }
额外注意点
- 如果你要兼容旧版本写法,可以用
Robolectric.buildActivity(LoginActivity.class, intent).setup().get()来替代上述的ActivityScenario写法,同样可以传入自定义Intent。 - 测试代码中不需要重新给控件设置点击监听,点击逻辑属于业务代码应该写在LoginActivity源码中,测试只需要模拟点击动作、校验点击后的结果即可。
内容的提问来源于stack exchange,提问作者user112016322
相关产品推荐
相关产品推荐

