我的活动中有一个片段,它将在其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.
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)
}
您不应该在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
}