Robolectric测试检查是否显示SnackBar?

时间:2018-06-13 15:58:10

标签: android robolectric

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

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

如何在我的Robolectric测试中断言这确实被称为?

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

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

4 个答案:

答案 0 :(得分:0)

而不是创建ShadowClass我找到了更好(更简单,更少hacky)的方式:

/**
 * @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中实现相同的

答案 1 :(得分:0)

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;
        }
    }

答案 2 :(得分:0)

使用自定义阴影:

在我的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 :(得分:0)

这是我的做法,遵循@vedant回答的一般思路:

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

这将与最新版本的材料设计库一起使用。 要搜索小吃店的TextView,也需要访问根视图。在根视图中,您具有从中获取字符串资源的上下文。