14

Unit test errors with this

Called loadFromPath(/system/framework/framework-res.apk, true); mode=binary sdk=28
java.lang.Exception: Main looper has queued unexecuted runnables. 
This might be the cause of the test failure. You might need a shadowOf(getMainLooper()).idle() call.

We are using Robolectric 4.4 compiling to target 29 but making sure we target 28 when running Unit tests due JDK still at 8 and not 9. Here is a block of code but I cannot seem to add the idle() for loopers in any place to make this happy

@RunWith(AndroidJUnit4::class)
@LooperMode(LooperMode.Mode.PAUSED)
class MyRoomActivityTest {

    @get:Rule
    val activityRule = ActivityTestRule(MyRoomActivity::class.java, true, false)

    @Inject lateinit var mockViewModel: NewMyRoomActivityViewModel

    @Inject lateinit var locationManager: LocationManager

    private var testViewStateLiveData: MutableLiveData<NewMyRoomActivityViewModel.MyRoomActivityViewState> = MutableLiveData()

    @Before
    fun setUp() {
        RobolectricTestGEComponent.GraphHolder.testGraph.inject(this)
        whenever(mockViewModel.viewState).thenReturn(testViewStateLiveData)
        shadowOf(getMainLooper()).idle() // doesn't work here
    }

    @Test
    fun `launch activity sets ViewModel room Id`() {
        val roomId = "TestMyRoomId"
        shadowOf(getMainLooper()).idle() // doesn't work here either 
        activityRule.launchActivity(MyRoomActivity.newIntent(ApplicationProvider.getApplicationContext(), roomId))  // fails here all the time
        verify(mockViewModel).initialize(roomId)
    }
.....
}
JPM
  • 9,077
  • 13
  • 78
  • 137
  • shadowOf(getMainLooper()).idle() can you move that below the activityRule.launchActivity? – Tobrun Apr 01 '21 at 18:57
  • It blows up at the launchActivity – JPM Apr 04 '21 at 22:42
  • 1
    @JPM any luck finding an answer for this question? – Shawn May 14 '21 at 03:53
  • I think my issue is that in the activity there is a call to the database using Room. That is what is failing. Bad design of data views and models is the problem. Room calls should happen not in the activity, then you can easily mock these data calls. Inherited code with bad design concepts is the issue. – JPM May 18 '21 at 13:56
  • 1
    In my case I solved this problem by calling delay(1000) function in runBlockingTest after executing asinchronous operation – Jamy Cake Aug 31 '21 at 18:23

1 Answers1

1

Adding an InstantTaskExecutorRule solved an issue for me.

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import org.junit.Rule

class Test {

    @get:Rule
    val executorRule = InstantTaskExecutorRule()

}
Goltsev Eugene
  • 3,325
  • 6
  • 25
  • 48