Testing Android Activity with Robolectric, duplicated Otto provider

2.1k views Asked by At

I have a little problem figuring out how to test my Activity using Robolectric 2.2. I am probably not correctly setting up the lifecycle or the entire test...

In my Activity, I have a Otto producer like this:

@Produce public GetAlarmList produceAlarmList() {
    Log.v(this, "Producing GetAlarmList event.");
    return new GetAlarmList(mAlarmList);
}

The following is my test.

@RunWith(RobolectricTestRunner.class)
public class GLarmListFragmentTests {

    //GLarmMain mActivity;
    ActivityController<GLarmMain> mController;

    @Before
    public void setUp() throws Exception {
        mController = Robolectric.buildActivity(GLarmMain.class);
    }

    @After
    public void tearDown() throws Exception {
        mController = mController.destroy();
    }

    @Test
    public void shouldHaveListFragment() {
        GLarmMain activity = mController.create().start().resume().visible().get();
        GLarmListFragment listFragment = (GLarmListFragment) activity.getSupportFragmentManager().findFragmentById(R.id.main_list_frag);
        assertNotNull(listFragment);
    }

    @Test
    public void shouldHaveListAdapter() {
        GLarmMain activity = mController.create().start().resume().visible().get();
        GLarmListFragment listFragment = (GLarmListFragment) activity.getSupportFragmentManager().findFragmentById(R.id.main_list_frag);
        FuncAlarmListAdapter listAdapter = (FuncAlarmListAdapter)listFragment.getListAdapter(); 
        assertNotNull(listAdapter);
    }
}

Every time I launch it, I receive:

java.lang.IllegalArgumentException: Producer method for type class ar.android.app.glarm.events.GetAlarmList found on type class ar.android.app.glarm.ui.GLarmMain, but already registered by type class ar.android.app.glarm.ui.GLarmMain.
    at com.squareup.otto.Bus.register(Bus.java:198)
    at ar.android.app.glarm.ui.GLarmMain.onResume(GLarmMain.java:461)
    at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1184)
    at android.app.Activity.performResume(Activity.java:5082)
    at org.fest.reflect.method.Invoker.invoke(Invoker.java:112)
    at org.robolectric.util.ActivityController$6.run(ActivityController.java:216)
    at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:256)
    at org.robolectric.util.ActivityController.invokeWhilePaused(ActivityController.java:214)
    at org.robolectric.util.ActivityController.resume(ActivityController.java:152)
    at ar.android.app.glarm.test.GLarmListFragmentTests.shouldHaveListAdapter(GLarmListFragmentTests.java:51)

Does someone have the same issue? How can I solve it?

1

There are 1 answers

0
Andrea Richiardi On

Found the problem, leaving it here for reference. I was not handling the pause()/onPause() life-cycle step and therefore never calling:

@Override
protected void onPause() {
    super.onPause();
    Log.v(this, ".onPause()");
    mBus.unregister(this); // unregisters.
}

Changing the above code as following solved:

@After
public void tearDown() throws Exception {
    mController = mController.pause().stop().destroy();
}