简体   繁体   English

android snackbar - 如何使用 roboelectric 进行测试

[英]android snackbar - how to test with roboelectric

From here we now know that robolectric does not have a shadow object but we can create a custom shadow object for a snackbar.It's ashame they have one for toast but not for snackbar.这里我们现在知道 robolectric 没有影子 object 但我们可以为小吃店创建一个自定义影子 object。很遗憾他们有一个用于吐司但没有用于小吃店。

I am showing a snackbar in my code when there is no.network connection.当没有网络连接时,我在我的代码中显示了一个 snackbar。 I'd like to know how can i write a unit test (with robolectric as the test runner) that can verify that a snackbar gets shown when there is no.network connection.我想知道如何编写一个单元测试(使用 robolectric 作为测试运行程序)来验证在没有网络连接时是否显示小吃店。

Its a little hard because the snackbar is not in xml. So when i declare my actually Activity controller it doesn't have a snackbar at that time.它有点难,因为小吃店不在 xml 中。所以当我声明我的实际活动 controller 时,它当时没有小吃店。

You know how to test a toast we have ShadowToast.getTextOfLatestToast() i want one for snackBar你知道如何测试吐司我们有ShadowToast.getTextOfLatestToast()我想要一个用于 snackBar

im currently using org.robolectric:robolectric:3.0-rc2 and dont see ShadowSnackbar.class available.我目前正在使用 org.robolectric:robolectric:3.0-rc2 并且看不到 ShadowSnackbar.class 可用。

It's actually explained in the blogpost how to add the ShadowToast class to enable testing. 实际上,在blogpost中解释了如何添加ShadowToast类以启用测试。

  1. Add the ShadowSnackbar to your test sources; 将ShadowSnackbar添加到测试源;
  2. Add the Snackbar class as an instrumented class in your custom Gradle test runner; 将Snackbar类添加为自定义Gradle测试运行器中的检测类;
  3. Add the ShadowSnackbar as a Shadow in your test; 在测试中添加ShadowSnackbar作为阴影;

In your app's code, you'll call on the Snackbar when no internet connection is available. 在您的应用程序代码中,当没有可用的互联网连接时,您将在Snackbar上调用。 Because of the configuration (eg intercepting of) the Snackbar as Instrumented class, the Shadow-variant of the class will be used. 由于Snackbar作为Instrumented类的配置(例如拦截),将使用该类的Shadow-variant。 You'll be able to evaluate the result at that moment. 您将能够在那一刻评估结果。

I posted a much simpler answer 我发布了一个更简单的答案

you can just do: 你可以这样做:

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

Implementation: 执行:

/**
 * @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
}

this is what worked for me, but it was a very simple use case这对我有用,但这是一个非常简单的用例

@Implements(Snackbar::class)
class CustomShadowSnackbar {

    companion object {
        val shownSnackbars = mutableListOf<Snackbar>()

        fun Snackbar.getTextMessage(): String {

            val view = (this.view as ViewGroup)
                .children
                .first { it is SnackbarContentLayout } as SnackbarContentLayout

            return view.messageView.text.toString()
        }

        fun clear() {
            shownSnackbars.clear()
        }
    }

    @RealObject
    lateinit var snackbar: Snackbar

    @Implementation
    fun show() {
        shownSnackbars.add(snackbar)
    }

    @Implementation
    fun __constructor__(
        context: Context,
        parent: ViewGroup,
        content: View,
        contentViewCallback: ContentViewCallback) {

        Shadow.invokeConstructor(
            Snackbar::class.java,
            snackbar,
            ReflectionHelpers.ClassParameter(Context::class.java, context),
            ReflectionHelpers.ClassParameter(ViewGroup::class.java, parent),
            ReflectionHelpers.ClassParameter(View::class.java, content),
            ReflectionHelpers.ClassParameter(ContentViewCallback::class.java, contentViewCallback)
        )
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM