8

我是 Android 测试的新手,我想测试一个 IntentService,我目前正在扩展 ServiceTestCase。

我正在尝试使用 aResultReceiver但问题是OnReceiveResult在测试用例中从未调用过。(我也尝试创建ResultReceiverwithnew Handler()作为参数 insetad ,null但结果相同。

我究竟做错了什么?测试的正确方法是IntentService什么?

这是服务:

public class MyService extends IntentService {

public MyService() {
    super("MyService");
}

public MyService(String name) {
    super(name);
}

@Override
protected void onHandleIntent(Intent intent) {
    final int action = intent.getIntExtra("action", 0);
    final int request = intent.getIntExtra("request", 0);
    final ResultReceiver receiver = (ResultReceiver) intent.getExtras().get("receiver");

    if (receiver == null) {
        return;
    }

    if (action == 0 || request == 0) {
        receiver.send(0, null);

        return;
    }
}

}

这是测试:

public void testHandleInvalidRequests() {
    ResultReceiver receiver = new ResultReceiver(null) {
        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            fail();
        }   
    };

    Intent intent = new Intent(mContext, MyService.class);
    intent.putExtra("receiver", receiver);
    startService(intent);

}
4

3 回答 3

4

我成功地测试了我的IntentService,我将在概念上向您展示我是如何做到的。

首先,您扩展 Android 服务测试类:ServiceTestCase<MyIntentService>. 然后你基本上IntentService像使用startService(intent).

由于被测服务是一个IntentService,它将在一个衍生的工作线程中完成所有工作。如果您不阻塞测试线程,那么您的测试方法将立即执行显然会失败的断言,因为后台的测试工作可能尚未完成。最终,测试方法将返回,您的测试将失败。

您需要做的是在startService. 使用 aReentrantLock和 Condition 调用await()它来执行此操作。

然后在后台IntentService执行onHandleIntent。我建议您扩展您的IntentServiceand override onHandleIntent,调用super.onHandleIntent(),然后向您的测试线程发出信号表明工作已经完成。在用于阻塞测试线程的相同锁和条件上执行此操作。

于 2013-04-06T19:33:57.647 回答
1

我知道这是旧的,但由于我遇到了同样的问题,我将在这里发布我最终如何设法在IntentService. 正如@Joerg 所说,这是一个线程问题。

public class MyServiceTest extends ServiceTestCase<MyService> {
    public MyServiceTest() {
        super(MyService.class);
    }

    public void testOnHandleIntent() throws Exception {
        Looper.prepare();
        final CountDownLatch latch = new CountDownLatch(1);

        ResultReceiver receiver = new ResultReceiver(new Handler()) {
            @Override
            protected void onReceiveResult(int resultCode, Bundle resultData) {
                latch.countDown();

                assertEquals(resultCode, 0);
                assertNull(resultData);
                fail();

                Looper.myLooper().quit();
            }
        };

        Intent intent = new Intent(getSystemContext(), MyService.class);
        intent.putExtra("receiver", receiver);
        getSystemContext().startService(intent);

        Looper.loop();

        assertThat(latch.getCount(), is(0L));
    }
}

Looper和类是必需的Handler,以便回调有一个要调用的线程。闩锁只是作为锁的一个例子,并作为一种在测试方法结束之前断言回调传递的代码的手段。

如果没有调用的quit()方法,则测试挂起。Looper

ServiceTestCase在最新版本的 Android 上已弃用,但替换 ( ServiceTestRule) 不支持IntentService...

于 2016-06-22T01:13:22.483 回答
0

如果startService()在测试文件中扩展ServiceTestCase<>,我在 Android Studio 1.1 的测试工具中发现ServiceTestCase不会IntentService通过onHandleIntent(). 有关更多信息,
请参阅IntentService 的 Android ServiceTestCase 。

于 2015-02-20T03:27:54.923 回答