如何在 Dialog 片段上运行单元测试? [英] How to run a unit test on a Dialog fragment?

查看:37
本文介绍了如何在 Dialog 片段上运行单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆