[英]how to JUnit test IntentService
I'm new into Android testing, I want to test an IntentService and I'm currently extending ServiceTestCase. 我是Android测试的新手,我想测试一个IntentService,我现在正在扩展ServiceTestCase。
I'm trying to use a ResultReceiver
but the problem is that OnReceiveResult
is never called within the test case. 我正在尝试使用
ResultReceiver
但问题是在OnReceiveResult
中永远不会调用OnReceiveResult
。 (I also tried creating the ResultReceiver
with new Handler()
as the argument insetad of null
but with the same result. (我还尝试使用
new Handler()
创建ResultReceiver
作为null
的参数insetad,但结果相同。
what am I doing wrong? 我究竟做错了什么? what is the proper way to test an
IntentService
? 测试
IntentService
的正确方法是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. 我成功地设法测试了我的
IntentService
,我将在概念上向您展示我是如何做到的。
First, you extend the Android Service Testing class: ServiceTestCase<MyIntentService>
. 首先,扩展Android Service Testing类:
ServiceTestCase<MyIntentService>
。 Then you basically start the IntentService
as you did using startService(intent)
. 然后你基本上就像使用
startService(intent)
一样启动IntentService
。
Since the service under test is an IntentService
, it will do all work in a spawned worker thread. 由于被测服务是一个
IntentService
,它将在生成的工作线程中完成所有工作。 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
. 您需要做的是在
startService
之后阻止您的测试线程。 Do this using a ReentrantLock
and a Condition calling await()
on it. 使用
ReentrantLock
和条件调用await()
来执行此操作。
The IntentService
then executes onHandleIntent
in the background. 该
IntentService
然后执行onHandleIntent
的背景。 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. 我建议你扩展你的
IntentService
并覆盖onHandleIntent
,调用super.onHandleIntent()
然后,告诉你的测试线程工作已经完成。 Do this on the same lock and condition used for blocking the testing thread. 在用于阻止测试线程的相同锁和条件上执行此操作。
If startService()
in the test file extends ServiceTestCase<>
, I've found in Android Studio 1.1's test facility that ServiceTestCase
does not instantiate an IntentService
object through onHandleIntent()
. 如果测试文件中的
startService()
扩展了ServiceTestCase<>
,我在Android Studio 1.1的测试工具中发现ServiceTestCase
没有通过onHandleIntent()
实例化一个IntentService
对象。
See Android ServiceTestCase for IntentService for more info. 有关详细信息,请参阅IntentService的Android ServiceTestCase 。
I know this is old, but as I had the same kind of problem, I'll post here how I finally managed to run a test on an IntentService
. 我知道这是旧的,但由于我遇到了同样的问题,我将在这里发布我最终如何设法在
IntentService
上运行测试。 As @Joerg said, it is a threading issue. 正如@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));
}
}
The Looper
and Handler
classes are necessary so that the callback has a thread to be called on. Looper
和Handler
类是必需的,以便回调有一个要调用的线程。 The latch is there only as an example of a lock and as a means to assert that the code passed by the callback before the end of the test method. 锁存器仅作为锁的示例,并且作为在测试方法结束之前断言回调传递的代码的手段。
If the quit()
method of the Looper
is not called, the test hangs. 如果未调用
Looper
的quit()
方法,则测试将挂起。
ServiceTestCase
is deprecated on the latest versions of Android, but the replacement ( ServiceTestRule
) doesn't support IntentService
... ServiceTestCase
在最新版本的Android上已弃用,但替换( ServiceTestRule
)不支持IntentService
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.