寻找一种方法将 Text 或 typeText 替换为嵌入 TextInputLayout 中的编辑文本。
我尝试过一些这样的事情:
perform(ViewActions.typeTextIntoFocusedView("String"));
但我总是以这个结束:
java.lang.RuntimeException: Action will not be performed because the target view does not match one or more of the following constraints:
(((is displayed on the screen to the user) and has focus on the screen to the user) and (supports input methods or is assignable from class: class android.widget.SearchView))
您必须创建一个新的
ViewAction
,因为 Espresso 无法访问嵌入在 EditText
中的 TextInputLayout
。你可以使用这样的东西
class TextInputLayoutActions {
class ReplaceTextAction(private val text: String): ViewAction {
override fun getDescription(): String {
return String.format(Locale.ROOT, "replace text(%s)", text)
}
override fun getConstraints(): Matcher<View> {
return allOf(isDisplayed(), ViewMatchers.isAssignableFrom(TextInputLayout::class.java))
}
override fun perform(uiController: UiController?, view: View?) {
(view as? TextInputLayout?)?.let {
it.editText?.setText(text)
}
}
}
companion object {
@JvmStatic
fun replaceText(text: String): ViewAction {
return actionWithAssertions(ReplaceTextAction(text))
}
}
}
然后像这样使用它
<ViewInteraction>.perform(TextInputLayoutActions.replaceText(<text>)
我尝试了这种方式如果您有权访问该活动,您也可以使用 findviewById
@Test
fun testSave() {
val book = Book(
title = "Machine Learning",
author = "Mohammed Fahim khan",
year = "2021", imageUrl = ""
)
val testViewModel = BookViewModel(FakeBookRepositoryIT())
launchFragmentInHiltContainer<BookDetailsFragment>(factory = fragmentFactory) {
viewModel = testViewModel
binding.etTitle.editText?.setText(book?.title.toString())
binding.etName.editText?.setText(book?.author.toString())
binding.etYear.editText?.setText(book?.year.toString())
}
/*onView(withId(R.id.et_title)).perform(replaceText(book.title))
onView(withId(R.id.et_name)).perform(replaceText(book.author))
onView(withId(R.id.et_year)).perform(replaceText(book.year))*/
onView(withId(R.id.btn_save)).perform(click())
val list = testViewModel.bookList.getOrAwaitValue()
assertThat(list).contains(book)
}
很简单:
onView(withId(R.id.YOUR_INPUT)).perform(typeText("bla bla"))
我知道我对这个问题晚了几年,我无法告诉你哪种方法是最好的,但到目前为止提出的答案对我来说似乎过于复杂。
在我自己的测试中,我成功地将值放入嵌入
TextInputEditText
中的 TextInputLayout
中,方法是识别父级 TextInputLayout
,然后找到具有以“EditText”结尾的类的后代视图,该类应覆盖 EditText
或 TextInputEditText
。
onView(allOf(
isDescendantOfA(withId(R.id.tilTicketNum)),
withClassName(endsWith("EditText")))
).perform(scrollTo(), replaceText("123456"));
如果您向
TextInputLayout
添加多个子视图,您可能会遇到这种方法的麻烦,但我很确定这违反了材料设计标准,所以我认为在大多数情况下这不应该成为问题。
仅供参考,我目前正在使用: