Android使用Espresso测试onActivityResult错误

问题描述 投票:0回答:2

我的活动中有一个片段,它将在其onActivityResult()上获取一些数据,并尝试更新UI。这是我的onActivityResult()代码:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {

            GET_USER_AUDIO_TO_TEXT_REQUEST_CODE -> {

                if (resultCode == RESULT_OK) {
                    data?.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)?.let {
                    val receivedCityName = it[0]
                    binding.homeCityNameEditTextView.setText(receivedCityName)//Update UI at this line
                    viewModel.fetchWeatherCity(receivedCityName)
                }
                } else {
                    Toast.makeText(activity, R.string.error_while_getting_data_from_recognizer, Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

因此,我尝试使用此部分的Espresso创建一些仪表测试:

 @Test
 fun checkActionsAfterReceivingDataInOnActivityResult() {

        val intent = Intent()
        intent.putStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS, arrayListOf(DEFAULT_CITY_NAME))

        activityRule.activity.supportFragmentManager
                .findFragmentByTag(HomeFragment.CLASS_NAME)
                ?.onActivityResult(
                        HomeFragment.GET_USER_AUDIO_TO_TEXT_REQUEST_CODE,
                        Activity.RESULT_OK,
                        intent
                )

    }

但是运行此Test method后会出现错误消息:该错误是由于我的ViewModel方法将要运行。通过在onActivityResult()中调用此行:

viewModel.fetchWeatherCity(receivedCityName)

这是它的错误:

java.lang.IllegalStateException: Cannot invoke setValue on a background thread
at android.arch.lifecycle.LiveData.assertMainThread(LiveData.java:435)
at android.arch.lifecycle.LiveData.setValue(LiveData.java:279)

并且由于通过此行更新了我的UI:

binding.homeCityNameEditTextView.setText(receivedCityName)//Update UI at this line

我也会收到此错误:

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
android android-espresso android-testing
2个回答
0
投票

Test instrumentation在不同的线程上运行,所以将test method-body with run on UI thread包起来。

activityRule.activity.runOnUiThread {
  // the test method body goes in here 
}

在您的情况下:-

activityRule.activity.runOnUiThread {
   activityRule.activity.supportFragmentManager
                .findFragmentByTag(HomeFragment.CLASS_NAME)
                ?.onActivityResult(
                        HomeFragment.GET_USER_AUDIO_TO_TEXT_REQUEST_CODE,
                        Activity.RESULT_OK,
                        intent)
}

0
投票

您不应该在Espresso测试中直接调用诸如onActivityResult之类的方法。由于这些测试是在不同的线程上执行的,因此您总是会得到相同的错误。如果要正确测试,则应考虑使用Espresso-Intents

@Test
fun checkActionsAfterReceivingDataInOnActivityResult() {
    val intent = Intent()
    intent.putStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS, arrayListOf(DEFAULT_CITY_NAME))

    intending(hasComponent(YourActivity.class.getName())).respondWith(ActivityResult(Activity.RESULT_OK, intent))

    // onView(...).perform(click())
    // First do something to cause your app to launch the intended activity

    // onView(...).check(matches(...))
    // Then test something on activity result
}
© www.soinside.com 2019 - 2024. All rights reserved.