导航组件-模拟Navcontroller图 [英] Navigation components - Mocking Navcontroller graph

查看:479
本文介绍了导航组件-模拟Navcontroller图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用导航组件,并试图通过仪器测试来测试我的Fragment.该片段具有一个自定义工具栏,该工具栏通过扩展功能在onViewCreated方法中初始化.

I'm using navigation components and I'm trying to test my Fragment with instrumented test. The fragment has a custom toolbar initialized in onViewCreated method by an extension function.

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    tbBlack.init()
}


fun androidx.appcompat.widget.Toolbar.init(
    menuId: Int? = null
) {
    title = ""
    menuId?.let {
        inflateMenu(it)
    }

    findNavController().let {
        it.graph.let { graph ->
            val configuration = AppBarConfiguration(graph)
            setupWithNavController(it, configuration)
        }
    }
}

在我的测试中初始化场景期间,由于导航控制器上的null图,测试崩溃.

During the initialization of the scenario in my instrumented test, the test crashes due to a null graph on the Nav Controller.

在测试中对nav控制器以及下面的图形进行了模拟:

The nav controller is mocked in the test, as well as the graph like below:

@RunWith(AndroidJUnit4::class)
class LoginFragmentTest {
    @Test
    fun testEmptyFields() {
        val mockNavController = mock(NavController::class.java)
        val mockGraph = mock(NavGraph::class.java)
        mockNavController.graph = mockGraph

        val scenario = launchFragmentInContainer(themeResId = R.style.AppTheme) {
            LoginFragment().also { fragment ->
                // In addition to returning a new instance of our Fragment,
                // get a callback whenever the fragment’s view is created
                // or destroyed so that we can set the mock NavController
                fragment.viewLifecycleOwnerLiveData.observeForever { viewLifecycleOwner ->
                    if (viewLifecycleOwner != null) {
                        // The fragment’s view has just been created
                        Navigation.setViewNavController(fragment.requireView(), mockNavController)
                    }
                }

            }
        }

        scenario.onFragment {
            it.run {
                val viewsIds =
                    listOf(R.id.etEmailAddress, R.id.etPassword)

                for (viewId in viewsIds) {
                    onView(ViewMatchers.withId(viewId))
                        .perform(ViewActions.replaceText(""))
                    Thread.sleep(500)
                    onView(ViewMatchers.withId(R.id.btLogin)).check(
                        ViewAssertions.matches(
                            CoreMatchers.not(
                                ViewMatchers.isEnabled()
                            )
                        )
                    )
                }
            }
        }
    }
}

我在navController的模拟中是否缺少某些东西?

Am I missing something in the mocking of the navController?

推荐答案

我使用了基本上,请执行以下操作:

Basically, do:

  1. 在您的(应用程序)gradle中导入依赖项:

dependencies {
  def nav_version = "2.3.0-alpha06"

  androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"
}

  1. 在androidTest中使用TestNavHostController模拟您的导航控制器:
  1. Mock your nav controller by using TestNavHostController in your androidTest:

 // Create a TestNavHostController
val navController = TestNavHostController(
            ApplicationProvider.getApplicationContext())

val fragmentArgs = Bundle().apply {
            putParcelable(Constants.RETAIL_CLICK_SOURCE_ID, RetailDetailsClicked.Source.LIST)
            putParcelable(Constants.RETAIL_ID, retail)
        }
        navController.setGraph(R.navigation.retail_details_graph)

        launchFragmentInContainer(
            fragmentArgs, R.style.AppTheme
        ) {
            RetailDetailsFragment().also { fragment ->
                // In addition to returning a new instance of our Fragment,
                // get a callback whenever the fragment’s view is created
                // or destroyed so that we can set the mock NavController
                fragment.viewLifecycleOwnerLiveData.observeForever { viewLifecycleOwner ->
                    if (viewLifecycleOwner != null) {
                        // The fragment’s view has just been created
                        Navigation.setViewNavController(fragment.requireView(), navController)
                    }
                }
            }
        }

就是这样!

这篇关于导航组件-模拟Navcontroller图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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