I'm trying to test basic unbound service with testing support library framework: http://developer.android.com/tools/testing-support-library/index.html
LocalService.java:
public class LocalService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
LocalServiceTest.java:
@RunWith(AndroidJUnit4.class)
public class LocalServiceTest {
@Rule
public final ServiceTestRule mServiceRule = new ServiceTestRule();
@Test
public void testWithUnboundService() throws TimeoutException {
Intent serviceIntent =
new Intent(InstrumentationRegistry.getTargetContext(), LocalService.class);
mServiceRule.startService(serviceIntent);
}
}
When I try to run test, I get following TimeoutException:
java.util.concurrent.TimeoutException: Waited for 5 SECONDS, but service was never connected
at android.support.test.rule.ServiceTestRule.waitOnLatch(ServiceTestRule.java:258)
at android.support.test.rule.ServiceTestRule.bindServiceAndWait(ServiceTestRule.java:207)
at android.support.test.rule.ServiceTestRule.startService(ServiceTestRule.java:137)
at com.example.android.testing.ServiceTestRuleSample.LocalServiceTest.testWithBoundService(LocalServiceTest.java:71)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at android.support.test.rule.ServiceTestRule$ServiceStatement.evaluate(ServiceTestRule.java:329)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:54)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:240)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1729)
Is it possible to test such kind of services with ServiceTestRule? If no, is there another appropriate way to start and stop services using JUnit 4 test classes?
I met the same issue as you. When I searched the reason in Android reference of ServiceTestRule, I found the reason is so simple.
Note: This method only supports services that allow clients to bind to them. In other words, if your service onBind(Intent) method returns null then a TimeoutException will be thrown.
Therefore I changed my onBind() method to return a non-null binder.
@Override
public IBinder onBind(Intent i) {
return new LocalBinder();
}
in which LocalBinder is defined as
public class LocalBinder extends Binder {
LocalService getService() {
return LocalService.this;
}
}
Then the TimeoutException went away!
I guess the reason of test failure is that your test runner cannot bind the service under test. Although the service is running since you have started it in your case, but test runner cannot detect if the service is running. It has to flag your test case as failed.
Try this one
@Rule
public final ServiceTestRule mServiceRule = ServiceTestRule.withTimeout(60L, TimeUnit.SECONDS);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With