如何JUnit测试IntentService测试、JUnit、IntentService

2023-09-08 00:00:30 作者:一生荒唐

我是新进的Andr​​oid测试,我想测试一个IntentService和我目前扩大ServiceTestCase。

我试图使用 ResultReceiver ,但问题是, OnReceiveResult 从未测试用例中调用。 (我也尝试创建 ResultReceiver 新的处理程序()作为参数insetad 但具有同样的效果。

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

这是该服务:

 公共类的MyService扩展IntentService {公共则将MyService(){    超(则将MyService);}公共则将MyService(字符串名称){    超(名);}@覆盖保护无效onHandleIntent(意向意图){    最终诠释行动= intent.getIntExtra(行动,0);    最终诠释请求= intent.getIntExtra(请求,0);    最后ResultReceiver接收器=(ResultReceiver)intent.getExtras()获得(接收器)。    如果(接收== NULL){        返回;    }    如果(行动== 0 ||请求== 0){        receiver.send(0,NULL);        返回;    }} 

}

Spring 利用junit 测试 Service注解出现java.lang.NullPointerException异常解决

和这是测试

 公共无效testHandleInvalidRequests(){    ResultReceiver接收器=新ResultReceiver(NULL){        @覆盖        保护无效onReceiveResult(INT结果code,捆绑resultData){            失败();        }    };    意向意图=新意图(mContext,MyService.class);    intent.putExtra(接收器,接收器);    startService(意向);} 

解决方案

我成功地设法测试我的 IntentService ,我会概念告诉你我是如何做的。

首先,扩展了Android服务测试类: ServiceTestCase< MyIntentService> 。然后,你基本上启动 IntentService 你没有使用 startService(意向)

由于测试的服务是一个 IntentService ,它会做一个生成的辅助线程的所有工作。如果你不阻止你的测试线程那么你的测试方法会立即做的断言,因为在后台的测试工作可能尚未完成,这将明显失败。最终,测试方法将返回和你的测试将失败。

您需要做的是阻止后 startService 测试线。为此使用的ReentrantLock 和条件调用等待()就可以了。

IntentService 然后执行 onHandleIntent 的背景。我建议您延长 IntentService 和覆盖 onHandleIntent ,要求 super.onHandleIntent(),之后,信号测试线程的工作已经完成。做这在用于阻塞线程的测试相同的锁和条件。

I'm new into Android testing, I want to test an IntentService and I'm currently extending ServiceTestCase.

I'm trying to use a ResultReceiver but the problem is that OnReceiveResult is never called within the test case. (I also tried creating the ResultReceiver with new Handler() as the argument insetad of null but with the same result.

what am I doing wrong? what is the proper way to test an IntentService ?

this is the service:

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;
    }
}

}

and this is the test:

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);

}

解决方案

I successfully managed to test my IntentService and I will show you conceptually how I did it.

First, you extend the Android Service Testing class: ServiceTestCase<MyIntentService>. Then you basically start the IntentService as you did using startService(intent).

Since the service under test is an IntentService, it will do all work in a spawned worker thread. If you do not block your test thread then your test method will immediately do assertions that will obviously fail since the test work in the background has probably not finished yet. Eventually, the test method will return and your test will fail.

What you need to do is to block your test thread after startService. Do this using a ReentrantLock and a Condition calling await() on it.

The IntentService then executes onHandleIntent in the background. I suggest you extend your IntentService and override onHandleIntent, calling super.onHandleIntent() and after that, signal your test thread that the work has been done. Do this on the same lock and condition used for blocking the testing thread.