测试Deferred有时会抛出NPE

时间:2019-07-15 08:38:12

标签: android kotlin android-testing coroutine kotlin-coroutines

我尝试编写UI测试,并遇到以下问题。我的测试:

    lateinit var mockShootingApi: ShootingApi

@Before
fun setup() {
    FragmentScenario.launchInContainer(MyFragment::class.java, null, object : FragmentFactory() {
        override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
            return MyFragment().apply {
                isNotTesting = false
                val realm = inMemoryRealm()
                realm.executeTransaction { it.deleteAll() }
                mockShootingApi = mock(ShootingApi::class.java)
                val shootingRepository = ShootingRepository(mockShootingApi, realm)
                viewModel = MyViewModel(ApplicationProvider.getApplicationContext(), shootingRepository)
            }
        }
    })
}

@Test
fun test_null_response() {
    runBlocking {  `when`(mockShootingApi.fetchDataAsync(ArgumentMatchers.anyInt())).thenReturn(async { PageResult<Data>() })}
    onView(withId(R.id.error_layout)).isVisible()
    onView(withId(R.id.recyclerView)).isGone()
}

@Test
fun test_empty_response() {
    runBlocking {  `when`(mockShootingApi.fetchDataAsync(ArgumentMatchers.anyInt())).thenReturn(async { emptyPageResult() })}
    onView(withId(R.id.error_layout)).isVisible()
    onView(withId(R.id.recyclerView)).isGone()
    onView(withId(R.id.error_text_view)).check(matches(withText("No results found")))
}

@Test
fun test_nonEmpty_response() {
    runBlocking { `when`(mockShootingApi.fetcDataAsync(ArgumentMatchers.anyInt())).thenReturn(async { nonEmptyPageResult() }) }
    onView(withId(R.id.error_layout)).isGone()
    onView(withId(R.id.recyclerView)).isVisible()
    onView(withId(R.id.recyclerView))
            .check(matches(atPosition(0, withText("test title"), R.id.titleTextView)))
    onView(withId(R.id.recyclerView))
            .check(matches(atPosition(0, withText("test description"), R.id.descriptionTextView)))
}

因此,有时并非总是如此,只是在存储库调用shootingApi.fetchDataAsync()出现的随机时刻,我得到了:

java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object kotlinx.coroutines.Deferred.await(kotlin.coroutines.Continuation)' on a null object reference

但同时shootingApi实例被模拟,并且不为null。它是随机发生的,例如可以成功完成2-3次测试,然后失败1次,然后再次成功1次,失败1-2次。有人有一些“为什么”的想法吗?

0 个答案:

没有答案