如何在 Dialog 片段上运行单元测试? [英] How to run a unit test on a Dialog fragment?
问题描述
我正在尝试为 DialogFragment 创建一个独立的单元测试,因此可以单独测试 DialogFragment.我正在使用 FragmentScenario 来启动 DialogFragment,现在我正在尝试确认是否显示了 Dialog 消息,但最终我将测试按钮点击.
I'm trying to create a stand-alone unit test for a DialogFragment, so the DialogFragment can be tested on its own. I'm using FragmentScenario to launch the DialogFragment, right now I'm trying to confirm that the Dialog message is displayed but eventually I'll be testing button clicks.
class ResetScoreDialog (val viewModel: MyViewModel) : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {
// Use the Builder class for convenient dialog construction
val builder = AlertDialog.Builder(it)
builder.setMessage(getString(R.string.resetscore_dialog_message))
.setPositiveButton(getString(R.string.confirm),
DialogInterface.OnClickListener { dialog, id ->
viewModel.resetScore()
})
// Create the AlertDialog object and return it
builder.create()
} ?: throw IllegalStateException("Activity cannot be null")
}
}
我的测试
@RunWith(RobolectricTestRunner::class)
class ResetScoreDialogTest {
private lateinit var scenario: FragmentScenario<ResetScoreDialog>
private lateinit var viewModel: MyViewModel
@Before
fun setup() {
viewModel = mock (MyViewModel::class.java)
scenario = launchFragmentInContainer(
factory = MainFragmentFactory(viewModel),
fragmentArgs = null,
themeResId = R.style.Theme_TDDScoreKeeper
)
}
@Test
fun `Dialog Displayed`() {
onView(withText(R.string.resetscore_dialog_message))
.check(matches(isDisplayed()))
}
}
运行测试时出现以下错误.
When I run the test I get the following error.
androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with string from resource id: <2131755113>
View Hierarchy:
+>DecorView{id=-1, visibility=VISIBLE, width=320, height=470, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params={(0,0)(fillxfill) ty=BASE_APPLICATION wanim=0x10302f8
fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
pfl=FORCE_DRAW_STATUS_BAR_BACKGROUND}, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}
|
+->LinearLayout{id=-1, visibility=VISIBLE, width=320, height=470, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@4ed1c9d4, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
|
+-->ViewStub{id=16908682, res-name=action_mode_bar_stub, visibility=GONE, width=0, height=0, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=true, is-selected=false, layout-params=android.widget.LinearLayout$LayoutParams@5853ff65, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0}
|
+-->FrameLayout{id=16908290, res-name=content, visibility=VISIBLE, width=320, height=470, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.LinearLayout$LayoutParams@188c12d2, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=0}
尝试了不同的解决方案.
Different solutions attempted.
scenario.onFragment {
onView(withText(R.string.resetscore_dialog_message))
.check(matches(isDisplayed()))
}
androidx.test.espresso.NoMatchingViewException:在层次结构中没有找到匹配的视图:来自资源 id 的字符串:<2131755113>
androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with string from resource id: <2131755113>
onView(withText(R.string.resetscore_dialog_message))
.inRoot(isDialog())
.check(matches(isDisplayed()))
androidx.test.espresso.NoMatchingRootException:匹配器是对话框"与以下任何根都不匹配:[Root{application-window-token=android.view.ViewRootImpl$W@b421ae4,window-token=android.view.ViewRootImpl$W@b421ae4, has-window-focus=true, layout-params-type=1, layout-params-string={(0,0)(fillxfill) ty=BASE_APPLICATION wanim=0x10302f8fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
androidx.test.espresso.NoMatchingRootException: Matcher 'is dialog' did not match any of the following roots: [Root{application-window-token=android.view.ViewRootImpl$W@b421ae4, window-token=android.view.ViewRootImpl$W@b421ae4, has-window-focus=true, layout-params-type=1, layout-params-string={(0,0)(fillxfill) ty=BASE_APPLICATION wanim=0x10302f8 fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
scenario.onFragment {
onView(withText(R.string.resetscore_dialog_message))
.inRoot(isDialog())
.check(matches(isDisplayed()))
}
androidx.test.espresso.NoMatchingRootException:匹配器是对话框"与以下任何根都不匹配:[Root{application-window-token=android.view.ViewRootImpl$W@65799e3f,window-token=android.view.ViewRootImpl$W@65799e3f, has-window-focus=true, layout-params-type=1, layout-params-string={(0,0)(fillxfill) ty=BASE_APPLICATION wanim=0x10302f8fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
androidx.test.espresso.NoMatchingRootException: Matcher 'is dialog' did not match any of the following roots: [Root{application-window-token=android.view.ViewRootImpl$W@65799e3f, window-token=android.view.ViewRootImpl$W@65799e3f, has-window-focus=true, layout-params-type=1, layout-params-string={(0,0)(fillxfill) ty=BASE_APPLICATION wanim=0x10302f8 fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
推荐答案
在测试 DialogFragment
时不能使用 launchFragmentInContainer
.
You can't use launchFragmentInContainer
while testing a DialogFragment
.
切换到launchFragment
扩展
在您的测试类中放置一个类似的函数并在每次测试之前调用它:
Put a similar function in your test class and call it before every test:
/**
* Launch YuorDialogFragment dialogfragment
*/
private fun openDialogFragment(): FragmentScenario<YuorDialogFragment> {
return launchFragment(
themeResId = R.style.AppTheme
) {
return@launchFragment YuorDialogFragment(
ViewModelUtil.createFor(mockViewModel)
);
}
}
将对话框测试放在 androidTest
文件夹中
Put the dialogs tests inside the androidTest
folder
这篇关于如何在 Dialog 片段上运行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!