Issue
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")
}
}
My Test
@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: 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: 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: 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
Solution
You can't use launchFragmentInContainer
while testing a DialogFragment
.
Switch to launchFragment
extension
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)
);
}
}
Put the dialogs tests inside the androidTest
folder
Answered By - MatPag
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.