【问题标题】:Robolectric test to check if a SnackBar is shown?用于检查是否显示 SnackBar 的 Robolectric 测试?
【发布时间】:2020-08-08 06:19:05
【问题描述】:

我在我的应用程序中调用以下代码:

Snackbar.make(this, R.string.empty_task_message, Snackbar.LENGTH_LONG)
    .show()

如何在我的 Robolectric 测试中断言这确实被调用了?

我正在考虑诸如遍历视图层次结构并搜索Snackbar 实例并检查视图是否可见。

这似乎是 Robolectric 中长期存在的问题。

【问题讨论】:

    标签: android robolectric


    【解决方案1】:

    与其创建ShadowClass,我发现了一种更好(更简单且不那么老套)的方法:

    /**
     * @return a TextView if a snackbar is shown anywhere in the view hierarchy.
     *
     * NOTE: calling Snackbar.make() does not create a snackbar. Only calling #show() will create it.
     *
     * If the textView is not-null you can check its text.
     */
    fun View.findSnackbarTextView(): TextView? {
      val possibleSnackbarContentLayout = findSnackbarLayout()?.getChildAt(0) as? SnackbarContentLayout
      return possibleSnackbarContentLayout
          ?.getChildAt(0) as? TextView
    }
    
    private fun View.findSnackbarLayout(): Snackbar.SnackbarLayout? {
      when (this) {
        is Snackbar.SnackbarLayout -> return this
        !is ViewGroup -> return null
      }
      // otherwise traverse the children
    
      // the compiler needs an explicit assert that `this` is an instance of ViewGroup
      this as ViewGroup
    
      (0 until childCount).forEach { i ->
        val possibleSnackbarLayout = getChildAt(i).findSnackbarLayout()
        if (possibleSnackbarLayout != null) return possibleSnackbarLayout
      }
      return null
    }
    

    用作:

    val textView: TextView? = rootView.findSnackbarTextView()
    assertThat(textView, `is`(notNullValue()))
    

    以上代码是kotlin,java中也可以实现

    【讨论】:

    • 这非常有帮助。非常干净和 Kotlin 风格
    • 你救了我的命!
    【解决方案2】:

    使用自定义阴影:

    在我的 github reop 中查看一个示例:https://github.com/cafesilencio/snackbarshadow

    val activity = Robolectric.buildActivity(MainActivity::class.java).create().start().resume().visible().get()
    
    activity.doSomethingToTriggerASnackbar()
    
    assertThat(ShadowSnackbar.getTextOfLatestSnackbar(), 'is'(activity.getString(R.string.ok))
    

    【讨论】:

      【解决方案3】:

      vedant1811s示例的修改Java版本:

          private TextView findSnackbarTextView(View rootView) {
              final Snackbar.SnackbarLayout snackbarLayout = findSnackbarLayout(rootView);
              return snackbarLayout == null ? null : (TextView) snackbarLayout.getChildAt(0)
                      .findViewById(android.support.design.R.id.snackbar_text);
          }
      
          private Snackbar.SnackbarLayout findSnackbarLayout(View rootView) {
              if (rootView instanceof Snackbar.SnackbarLayout) {
                  return (Snackbar.SnackbarLayout) rootView;
              } else if (rootView instanceof ViewGroup) {
                  for (int i = 0; i < ((ViewGroup) rootView).getChildCount(); i++) {
                      if (findSnackbarLayout(((ViewGroup) rootView).getChildAt(i)) != null) {
                          return findSnackbarLayout(((ViewGroup) rootView).getChildAt(i));
                      }
                  }
                  return null;
              } else {
                  return null;
              }
          }
      

      【讨论】:

      • 注意:我遇到了时间问题,测试有时找不到小吃店。未完成调查...
      【解决方案4】:

      按照@vedant 回答的一般思路,我就是这样做的:

      assertEquals(resources.getString(R.string.empty_task_message),
                  rootView.findViewById<TextView>(com.google.android.material.R.id.snackbar_text).text.toString())
      

      这将适用于最新版本的材料设计库。 还需要访问根视图,以搜索小吃店的TextView。使用根视图,您可以从上下文中获取字符串资源。

      【讨论】:

        猜你喜欢
        • 2020-08-10
        • 2017-08-24
        • 2019-08-18
        • 2020-12-07
        • 2015-07-23
        • 1970-01-01
        • 2012-11-01
        • 2011-02-01
        • 1970-01-01
        相关资源
        最近更新 更多