I'm trying to write instrumentation test for my NetworkMonitorService
as described in the official "testing your service" documentation.
Currently I'm stuck because I can't figure out how can I grab a reference to the started service in order to inject mocks into it and assert behavior.
My code:
@RunWith(AndroidJUnit4.class)
@SmallTest
public class NetworkMonitorServiceTest {
@Rule public final ServiceTestRule mServiceTestRule = new ServiceTestRule();
@Test
public void serviceStarted_someEventHappenedInOnStartCommand() {
try {
mServiceTestRule.startService(new Intent(
InstrumentationRegistry.getTargetContext(),
NetworkMonitorService.class));
} catch (TimeoutException e) {
throw new RuntimeException("timed out");
}
// I need a reference to the started service in order to assert that some event happened
// in onStartCommand()...
}
}
The service in question doesn't support binding. I think that if I'd implement support for binding and then use this in test in order to get a reference to the service it could work. However, I don't like writing production code just for sake of supporting test cases...
So, how can I test (instrumentation test) a Service
that doesn't support binding?
I found a very simple way for doing this. You can just perform a binding and you'll get the reference to the already running service, there are no conflicts with service creation because you already started it with
onStartCommand
, if you check you will seeonCreate
is called only once so you can be sure it is the same service. Just add the following after your sample:I hope it helps.
this works at least for bound services:
to access fields, annotate with
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
Replace your application with special version "for tests". Do it by providing custom instrumentation test runner. Mock your dependencies it this "app for tests". See for details
Here is a simplified example how "app for test" can be used. Let's assume you want to mock network layer (eg.
Api
) during tests.In the example dependency injection is done via application's method
getApi
. But you can use Dagger or any others approaches in the same way.