12

I wanted to test a class in a framework that starts different services based on an intent. However, I am having issues create the TestService inside the androidTest/ when connected android test is being run. The getService method returns null.

Thanks in advance for any guidance and help!

@RunWith(AndroidJUnit4.class)
public class WakefulIntentSenderTest {
    private static final String SOME_ACTION = "someAction";

    private static class TestService extends Service {
        private boolean mCalled;

        @Override
        public void onCreate() {
            super.onCreate();
        }

        @Override
        public IBinder onBind(final Intent intent) {
            return null;
        }

        @Override
        public int onStartCommand(final Intent intent, final int flags, final int startId) {
            mCalled = true;
            return 0;
        }

        public boolean wasCalled() {
            return mCalled;
        }

        public class TestServiceBinder extends Binder {

        public TestService getService() {
            return TestService.this;
        }
    }

    @Test
    public void testWithBoundService() throws TimeoutException {
        // Create the service Intent.
        Intent serviceIntent =
                new Intent(InstrumentationRegistry.getTargetContext(), TestService.class);

        InstrumentationRegistry.getTargetContext().startService(intent);

        // Bind the service and grab a reference to the binder.
        IBinder binder = mServiceRule.bindService(serviceIntent);

        // Get the reference to the service, or you can call public methods on the binder directly.
        TestService service = ((TestService.TestServiceBinder) binder).getService();

        // Verify that the service is working correctly.
        assertEquals(service.wasCalled(), true);
    }
}

I also have other questions where the TestService is really created inside the "Test" package. If I try to start the TestService via the app context, it would give me an error saying Unable to start service Intent { cmp=com.example.abc.test/com.example.abc.WakefulIntentSenderTest$TestService } U=0: not found error.

And above code is really just to demonstrate if I can start a service.

Some more info... InstrumentationRegistry would return com.example.abc when getTargetContext() is called, and com.example.abc.test when getContext() is called.

What I really wanted to test is a class behind com.example.abc that uses a the PowerManager to start a Service with a Wakelock. But that's in the back of my mind for now because I can't even start a Service from the Test package.

Having TestService inside the main package is also not an option for me unfortunately :(

Dillon
  • 364
  • 5
  • 18
  • 1
    I think you would need to create a test build variant (not just plain `androidTest`) with a separate `AndroidManifest.xml` declaring the test service for this technique to work. See [Using non-production Activity for testing with Android Studio](https://stackoverflow.com/questions/22024537/using-non-production-activity-for-testing-with-android-studio) – David Rawson Jan 13 '18 at 08:41

2 Answers2

4

https://developer.android.com/training/testing/integration-testing/service-testing.html

Android provides a direct way to get a reference to service.

user3219477
  • 134
  • 3
  • 10
0

You need to return an instance of your TestServiceBinder class in TestService#onBind