Тестирование инструментария не выполняется с помощью асинхронных операций с использованием CountingIdlingResource

В моих тестах инструментовки, testZoomControls всегда выполняется раньше CountingIdlingResource уменьшается и вызывает map has not been initialized исключение.

Как это возможно?

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) {
            this@MapViewTestActivity.map = map
            idlingResource.decrement()
        }
    })
}

1 ответ

Решение

Тебе нужно Espresso.onView(..).check(..) или подобный для этого IdlingResource, чтобы иметь какое-либо значение. В этом случае Espresso будет ждать, пока все IdlingRsources не будут работать, а затем перейдет к следующей строке кода:

@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)
}
Другие вопросы по тегам