无法在Android JUnit 4检测测试中启动未绑定服务

Ram*_*dny 6 android android-testing

我正在尝试使用测试支持库框架测试基本的未绑定服务: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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试运行测试时,我得到以下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)
Run Code Online (Sandbox Code Playgroud)

是否可以使用ServiceTestRule测试此类服务?如果不是,是否有其他适当的方法来启动和停止使用JUnit 4测试类的服务?

Hui*_*han 7

我遇到了和你一样的问题。当我在ServiceTestRule 的Android 参考中搜索原因时,我发现原因很简单。

注意:此方法仅支持允许客户端绑定到它们的服务。换句话说,如果您的服务 onBind(Intent) 方法返回 null,则将抛出 TimeoutException。

因此我改变了我的 onBind() 方法来返回一个非空的绑定器。

@Override
public IBinder onBind(Intent i) {
    return new LocalBinder();
}
Run Code Online (Sandbox Code Playgroud)

其中 LocalBinder 被定义为

public class LocalBinder extends Binder {
    LocalService getService() {
        return LocalService.this;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后 TimeoutException 消失了!

我猜测试失败的原因是您的测试运行程序无法绑定被测服务。尽管该服务在您的案例中启动后正在运行,但测试运行器无法检测该服务是否正在运行。它必须将您的测试用例标记为失败。


小智 3

试试这个

@Rule
public final ServiceTestRule mServiceRule = ServiceTestRule.withTimeout(60L, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)