Eventbus: Can't unit test classes that use EventBus

Created on 7 Feb 2017  ·  5Comments  ·  Source: greenrobot/EventBus

I want to write some unit tests for classes that have their own EventBus instances, but it won't work because EventBus uses Android's Handler in its constructor. Using Otto I'm able to do it, but I want to use EventBus instead. Any ideas?

java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details.

    at android.os.Looper.getMainLooper(Looper.java)
    at org.greenrobot.eventbus.EventBus.<init>(EventBus.java:111)
    at org.greenrobot.eventbus.EventBus.<init>(EventBus.java:104)
    (...)

Process finished with exit code 255

Most helpful comment

@gsteigert My team and I ran into this exact problem while integrating GreenRobot Eventbus. We wanted to verify that the eventbus was posting a specific event but not the execution of the posted event.

You can achieve this via reflection and mockito mocks.

Java:

Field field = EventBus.class.getDeclaredField("defaultInstance");
if (!field.isAccessible()) field.setAccessible(true);
field.set(null, Mockito.mock(EventBus.class));

Kotlin:

val field = EventBus::class.java.getDeclaredField("defaultInstance")
if (!field.isAccessible) field.isAccessible = true
field.set(null, mock<EventBus>())

All 5 comments

You are probably trying to use a local unit test. But as you found out, EventBus depends on some Android features. So you have to use an instrumented unit test that runs on an Android device instead.
-ut

Ok, thanks!

@gsteigert My team and I ran into this exact problem while integrating GreenRobot Eventbus. We wanted to verify that the eventbus was posting a specific event but not the execution of the posted event.

You can achieve this via reflection and mockito mocks.

Java:

Field field = EventBus.class.getDeclaredField("defaultInstance");
if (!field.isAccessible()) field.setAccessible(true);
field.set(null, Mockito.mock(EventBus.class));

Kotlin:

val field = EventBus::class.java.getDeclaredField("defaultInstance")
if (!field.isAccessible) field.isAccessible = true
field.set(null, mock<EventBus>())

thank @jmholtan for your answer, it works for me!

Note that as of version 3.1.1 EventBus also works for plain-Java projects, so also for Android local unit tests. Though note that some thread modes may behave differently. -ut

Was this page helpful?
0 / 5 - 0 ratings