Skip to content

ServiceTestRule is not able to start/bind a service #935

@ampeixoto

Description

@ampeixoto

Description

Following the steps provided here , I was expecting to be able to start/bind to a service a robolectric test. However, the test keep falling with error: Waited for 5 SECONDS, but service was never connected

Steps to Reproduce

I created a minimal project that is possible to replicate the issue (see below). In terms of code, here it is:

internal class DummyTestService : Service() {

    override fun onBind(intent: Intent?): IBinder {
        return LocalBinder()
    }

    inner class LocalBinder : Binder() {
        // Return this instance of DummyTestService so clients can call public methods
        fun getService(): DummyTestService = this@DummyTestService
    }
}

And the test:

@RunWith(AndroidJUnit4::class)
@MediumTest
internal class DummyTestServiceTest {

    @get:Rule
    val serviceRule = ServiceTestRule()

    @Test
    fun testWithStartedService() {
        serviceRule.startService(
            Intent(
                ApplicationProvider.getApplicationContext<Context>(),
                DummyTestService::class.java
            )
        )

        // Add your test code here.
    }

    @Test
    fun testWithBoundService() {
        val app = ApplicationProvider.getApplicationContext<Context>()
        val binder = serviceRule.bindService(
            Intent(
                app,
                DummyTestService::class.java
            )
        )
        val service = (binder as DummyTestService.LocalBinder).getService()
        Assert.assertNotNull(service)
    }

}

Expected Results

How be able to start and bind to a service from a robolectric test.

Actual Results

Instead the test fails with the following stacktrace:

Main looper has queued unexecuted runnables. This might be the cause of the test failure. You might need a shadowOf(getMainLooper()).idle() call.
java.lang.Exception: Main looper has queued unexecuted runnables. This might be the cause of the test failure. You might need a shadowOf(getMainLooper()).idle() call.
	at org.robolectric.android.internal.AndroidTestEnvironment.checkStateAfterTestFailure(AndroidTestEnvironment.java:502)
	at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:581)
	at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:278)
	at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.util.concurrent.TimeoutException: Waited for 5 SECONDS, but service was never connected
	at androidx.test.rule.ServiceTestRule.waitOnLatch(ServiceTestRule.java:272)
	at androidx.test.rule.ServiceTestRule.bindServiceAndWait(ServiceTestRule.java:205)
	at androidx.test.rule.ServiceTestRule.bindService(ServiceTestRule.java:149)
	at com.myapps.myapplication.DummyTestServiceTest.testWithBoundService(DummyTestServiceTest.kt:36)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at androidx.test.rule.ServiceTestRule$ServiceStatement.evaluate(ServiceTestRule.java:337)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:575)
	... 6 more

AndroidX Test and Android OS Versions

    testImplementation "junit:junit:4.13.1"
    testImplementation "androidx.test:runner:1.3.0"
    testImplementation "androidx.test.ext:junit:1.1.2"
    testImplementation "org.robolectric:robolectric:4.5.1"
    testImplementation "org.robolectric:shadows-multidex:4.5.1"

Using Android Studio 2020.3.1 Canary 14

Link to a public git repo demonstrating the problem:

sandbox.zip

Am I missing something or this is really a bug?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions