使用Robolectric测试带有意图附加项的服务启动?

5

我可以使用Robolectric测试活动是否启动了服务,并使用意图传递特定的Bundle吗?答案:可以!

我想编写一个基于Robolectric的测试,以测试我的MainActivity是否使用传递给Intent的特定数字启动了MyService

在“MainActivity.java”文件中,我有以下方法:

public void startMyService() {
  Intent i = new Intent(this, MyService.class);
  Bundle intentExtras = new Bundle();
  // TODO: Put magic number in the bundle
  i.putExtras(intentExtras);
  startService(i);
}

这是我的测试用例 "MainActivityTest.java":

import ...

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class)
public class MainActivityTest extends TestCase {
  @Override
  protected void setUp() throws Exception {
    super.setUp();
  }

  @Override
  protected void tearDown() throws Exception {
    super.tearDown();
  }

  @Test
  public void testShallPassMagicNumberToMyService() {
    MainActivity activityUnderTest = Robolectric.setupActivity(MainActivity.class);
    activityUnderTest.startMyService();

    Intent receivedIntent = shadowOf(activityUnderTest).getNextStartedService();

    assertNotNull("No intents received by test case!", receivedIntent);

    Bundle intentExtras = receivedIntent.getExtras();
    assertNotNull("No intent extras!", intentExtras);

    long receivedMagicNumber = intentExtras.
            getLong(MyService.INTENT_ARGUMENT_MAGIC_NUMBER);

    assertFalse("Magic number is not included with the intent extras!",
            (receivedMagicNumber == 0L));  // Zero is default if no 'long' was put in the extras
  }
}

所以,我的问题是: 我能用Robolectric来完成这个目的吗? 我想我已经解决了这个问题,请看下面的答案……
测试用例无法工作,因为它报告“没有意图扩展!”。使用调试器,我注意到Intent.putExtras()在Robolectric环境中没有任何效果。i.mExtras (Intent.mExtras)属性在我在设备上运行应用程序时被正确设置为Bundle引用。当我运行测试用例时,它是null。我认为这暗示了我的问题的答案是否定的,那么我应该放弃这个测试用例还是有办法完成这个测试?
编辑:根据我的实际问题,更正了示例startMyActivity()方法:似乎只有在Bundle中有一些内容时,才会填充Intent.mExtras属性(?)。这与活动Android环境不同,这是我通过调试器分析的。
1个回答

1
我在展示我的示例代码时并不完全准确! 我已经更新了示例以显示我遇到问题的代码。
结果发现,在Robolectric环境和真实的Android环境中,管理Intent的方式存在差异。 在Robolectric中,除非在添加到Intent作为extras的Bundle中有内容,否则Intent.putExtras()不会填充Intent.mExtras。

1
有趣。我认为默认情况下Robolectric正在使用API16 AOSP。您正在调试哪个Android版本?您能否在测试中添加@Config{emulateSdk=<android version>}?我只是想知道它是特定于Android版本还是Robolectric。 - Eugen Martynov
嗨Eugen,感谢您的提示。我正在为应用程序使用targetSdkVersion 19。我尝试了在测试中使用emulateSdk = {16,18,21},但结果始终相同:如果我使用一个新的Bundle进行Intent.putExtras(),那么在Robolectric环境中Intent.mExtras仍然为null。 "AOSP"代表什么? - jokki
AOSP 是 Android 开放源代码项目。 - Eugen Martynov
让我检查一下Robolectric的源代码 :) - Eugen Martynov
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Eugen Martynov
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接