How to check JUnit IntentService

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

I am trying to use ResultReceiver , but the problem is that OnReceiveResult never called in the test case. (I also tried creating a ResultReceiver with new Handler() as an insertion of the null argument, but with the same result.

what am I doing wrong? What is the correct way to test IntentService ?

this is a 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); } 
+6
source share
3 answers

I was able to successfully 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 run in the IntentService . If you do not block the test thread, then your test method will immediately make statements that will obviously fail, because the test work in the background is probably not completed yet. In the end, the test method will return and your test will fail.

What you need to do is block the test thread after startService . Do this using a ReentrantLock and a condition that calls await() on it.

Then the IntentService runs onHandleIntent in the background. I suggest that you expand your IntentService and override onHandleIntent by calling super.onHandleIntent() , and then tell the test thread that the work is done. Do this with the same lock and condition used to lock the test thread.

+4
source

If startService() in the test file extends ServiceTestCase<> , I found in the test on Android Studio 1.1 that ServiceTestCase does not create an IntentService object via onHandleIntent() .
For more information, see Android ServiceTestCase for IntentService .

0
source

I know this is old, but since I had the same problem, I will post here how I finally managed to run the test on the IntentService . As @Joerg said, this is a threading issue.

 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 required for the callback to invoke the thread. The latch exists only as an example of locking and as a means to confirm that the code passed in by the callback to the end of the test method.

If the quit() Looper method is not called, the test freezes.

ServiceTestCase deprecated in recent versions of Android, but the replacement ( ServiceTestRule ) does not support IntentService ...

0
source

Source: https://habr.com/ru/post/922672/


All Articles