dgngulcan
dgngulcan

Reputation: 3149

Instrumentation test fails with Async operations using CountingIdlingResource

In my instrumentation tests, testZoomControls is always executed before CountingIdlingResource is decremented and causing map has not been initialized exception.

How is it possible?

MapViewUiControlsTest.kt

@RunWith(AndroidJUnit4::class)
class MapViewUiControlsTest {

    private lateinit var mapView: MapView
    private lateinit var map: Map

    @Rule
    @JvmField
    val activityRule: ActivityTestRule<MapViewTestActivity> = ActivityTestRule(
        MapViewTestActivity::class.java
    )

    @Rule
    @JvmField
    val grantPermissionRule: GrantPermissionRule =
        GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION)

    private lateinit var idlingResource: CountingIdlingResource

    @Before
    @UiThreadTest
    fun init() {
        MockitoAnnotations.initMocks(this)

        idlingResource = activityRule.activity.idlingResource

        idlingResource.registerIdleTransitionCallback({
            map = activityRule.activity.map
            mapView = activityRule.activity.mapView
        })

        IdlingRegistry.getInstance().register(idlingResource)

        activityRule.activity.init()
    }

    @After
    @UiThreadTest
    fun cleanup() {
        IdlingRegistry.getInstance().unregister(idlingResource)
    }

    @Test
    @UiThreadTest
    fun testZoomControls() {
        map.getMapOptions().zoomControlsEnabled = true
        Assert.assertEquals(View.VISIBLE, mapView.zoomControlsView.visibility)
    }

}

MapViewTestActivity.kt

val idlingResource = CountingIdlingResource("dummy_resource", true)

fun init() {
    idlingResource.increment()
    mapView.getMapAsync(onMapReadyCallback = object : OnMapReadyCallback {
        override fun onMapReady(map: Map) {
            [email protected] = map
            idlingResource.decrement()
        }
    })
}

Upvotes: 2

Views: 319

Answers (1)

Anatolii
Anatolii

Reputation: 14670

You need Espresso.onView(..).check(..) or similar for this IdlingResource to make any difference. In this case, Espresso will wait until all the IdlingRsources are idle and then go on to the next line of code:

@Test
@UiThreadTest
fun testZoomControls() {
    //this will wait until your IdlingResource is idle
    Espresso.onView(<your map view matcher>).check(matches(isDisplayed()));

    map.getMapOptions().zoomControlsEnabled = true
    Assert.assertEquals(View.VISIBLE, mapView.zoomControlsView.visibility)
}

Upvotes: 0

Related Questions