Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing Activity.startService() call?

Attempting to write my first Android-by-TDD app (I've written a few small Android apps without TDD, so am familiar with the environment), but I can't seem to get my head around how to write my first test.

The scenario:

I have an activity, TasksActivity, and a service, TasksService. I need to test that TasksActivity starts TasksService in its onStart() method.

The test I've written is this:

public class ServiceControlTest extends ActivityUnitTestCase<TasksActivity>{
public ServiceControlTest() {
    super(TasksActivity.class);
}

public void testStartServiceOnInit () {
    final AtomicBoolean serviceStarted = new AtomicBoolean(false);
    setActivityContext(new MockContext() {
        @Override
        public ComponentName startService(Intent service) {
            Log.v("mockcontext", "Start service: " + service.toUri(0));
            if (service.getComponent().getClassName().equals (TasksService.class.getName()))
                serviceStarted.set(true);
            return service.getComponent();
        }
    });
    startActivity(new Intent(), null, null);
    assertTrue ("Service should have been started", serviceStarted.get());
}           
}

In my onCreate() method in TasksActivity I have:

    startService(new Intent(this, TasksService.class));

I have also tried

    getBaseContext().startService(new Intent(this, TasksService.class));

But in neither case does my MockContext's startService method get called. Is there a way I can set up interception of this method? I'd really rather not have to start wrapping the basic Android APIs in order to perform such basic tests...

like image 869
Jules Avatar asked Feb 15 '12 13:02

Jules


1 Answers

Just to summarise the conversation with Brian Dupuis in comments, the problem was that MockContext doesn't provide facilities that are required by the test instrumentation in order to correctly call onCreate(). Switch from MockContext to ContextWrapper solved this problem.

The working test therefore looks like this:

public void testStartServiceOnInit () {
    final AtomicBoolean serviceStarted = new AtomicBoolean(false);
    setActivityContext(new ContextWrapper(getInstrumentation().getTargetContext()) {
        @Override
        public ComponentName startService(Intent service) {
            Log.v("mockcontext", "Start service: " + service.toUri(0));
            if (service.getComponent().getClassName().equals ("net.meridiandigital.tasks.TasksService"))
                serviceStarted.set(true);
            return service.getComponent();
        }
    });
    startActivity(new Intent(), null, null);
    assertTrue ("Service should have been started", serviceStarted.get());
}
like image 172
Jules Avatar answered Sep 23 '22 11:09

Jules