【问题标题】:Robolectric and IntentServicesRobolectric 和 IntentServices
【发布时间】:2012-07-26 20:14:54
【问题描述】:

使用 Robolectric,如何测试将 IntentService 广播为响应的 IntentService?

假设以下类:

class MyService extends IntentService {
    @Override
    protected void onHandleIntent(Intent intent) {
        LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("action"));
    }
}

在我的测试用例中,我正在尝试做这样的事情:

@RunWith(RobolectricTestRunner.class)
public class MyServiceTest{
    @Test
    public void testPurchaseHappyPath() throws Exception {

        Context context = new Activity();

        // register broadcast receiver
        BroadcastReceiver br = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                // test logic to ensure that this is called
            }

        };
        context.registerReceiver(br, new IntentFilter("action"));

        // This doesn't work
        context.startService(new Intent(context, MyService.class));

    }

}

MyService 永远不会使用这种方法启动。我对 Robolectric 比较陌生,所以我可能遗漏了一些明显的东西。在调用 startService 之前我必须做某种绑定吗?我已经通过在上下文中调用 sendBroadcast 来验证广播是否有效。有什么想法吗?

【问题讨论】:

  • 我没有适合您的具体解决方案,但我认为您必须使用 mockito 模拟广播接收器才能在您的代码中调用 onReceive。或者更简单的方法是将 onReceive 中的逻辑提取到单独的测试用例中。
  • 广播接收器实际上工作得很好。正如我在上面帖子底部所说,调用 context.sendBroadcast 会进入 onReceive。这是我看不到发生的服务初始化。
  • 您找到解决方案了吗?我在尝试测试 IntentService 时遇到了同样的问题

标签: android unit-testing broadcastreceiver intentservice robolectric


【解决方案1】:

您无法像尝试那样测试服务初始化。当您在 Robolectric 下创建新活动时,您返回的活动实际上是 ShadowActivity(有点)。这意味着当您调用startService 时,实际执行的方法是this one,它只是调用ShadowApplication#startService。这是该方法的内容:

@Implementation
@Override
public ComponentName startService(Intent intent) {
    startedServices.add(intent);
    return new ComponentName("some.service.package", "SomeServiceName-FIXME");
}

您会注意到它实际上并没有尝试启动您的服务。它只是指出您试图启动该服务。这对于某些被测代码应该启动服务的情况很有用。

如果你想测试实际的服务,我认为你需要为初始化位模拟服务生命周期。这样的事情可能会起作用:

@RunWith(RobolectricTestRunner.class)
public class MyServiceTest{
    @Test
    public void testPurchaseHappyPath() throws Exception {

        Intent startIntent = new Intent(Robolectric.application, MyService.class);
        MyService service = new MyService();
        service.onCreate();
        service.onStartCommand(startIntent, 0, 42);

        // TODO: test test test

        service.onDestroy();
    }
}

我不熟悉 Robolectric 如何对待 BroadcastReceivers,所以我把它省略了。

编辑:在 JUnit @Before/@After 方法中创建/销毁服务可能更有意义,这将允许您的测试仅包含 onStartCommand 和“测试测试测试”位。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多