5

我有一个实例,其中显示和隐藏几个按钮取决于 ViewPager 中显示的页面。使用动画师显示和隐藏。有没有办法检查/延迟单元测试,直到完成?

我正在使用 Robolectric,因为这可能是相关的。我试着打电话Robolectric.runUiThreadTasksIncludingDelayedTasks();,但这似乎没有解决任何问题。

动画代码如下:

public static void regularFadeView(final boolean show, final View view) {
    view.animate()
            .setInterpolator(mDecelerateInterpolator)
            .alpha(show ? 1 : 0)
            .setListener(new SimpleAnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {
                    if (show) view.setVisibility(View.VISIBLE);
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    if (!show) view.setVisibility(View.INVISIBLE);
                }
            })
            .start();
}
4

3 回答 3

6

我认为你可以重新安排方法来解决这个问题。这是通过将 SimpleAnimatorListener 提取到受保护的变量中,然后基于该变量进行单元测试。就像是:

@VisibleForTesting
SimpleAnimatorListener getAnimationListener(boolean show, View view) {
   return new SimpleAnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
            if (show) view.setVisibility(View.VISIBLE);
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            if (!show) view.setVisibility(View.INVISIBLE);
        }
    }

public static void regularFadeView(boolean show, View view) {
     view.animate()
        .setInterpolator(mDecelerateInterpolator)
        .alpha(show ? 1 : 0)
        .setListener(getAnimationListener(show, view))
        .start();
}

然后在你的测试中:

private void shouldShowViewWhenShowIsTrue() {
     View mockedView = Mockito.mock(View.class);
     SimpleAnimatorListener animationListener = getAnimationListener(true, mockedView);
     animationListener.onAnimationStart(null);
     Mockito.verify(mockedView).setVisibility(View.VISIBLE);
}

更好的办法是创建一个扩展 SimpleAnimatorListener 的 FadeAnimationListener,而不是像 getAnimationListener() 这样的方法,并将动画逻辑放在那里。

希望这可以帮助!

于 2014-05-05T21:42:59.173 回答
3

我最终创建了一个 AnimationUtility 接口和一个真实和虚假的实现。伪造的实现立即将视图设置为可见/隐藏,而不是执行动画。我根据适当的上下文动态注入真/假。

于 2014-05-06T22:24:18.030 回答
0

在这里,我提出了基于ValueAnimator类的解决方案。我使用mockk库。

fun mockObjectAnimators() {
    mockkStatic(ObjectAnimator::class)
    val targetSlot = slot<Any>()
    val propertySlot = slot<String>()
    every {
        ObjectAnimator.ofFloat(capture(targetSlot), capture(propertySlot), *anyFloatVararg())
    } answers {
        spyk(
            ObjectAnimator().apply {
                target = targetSlot.captured
                duration = 0L
                setPropertyName(propertySlot.captured)
            }
        ).also { spy ->
            every { spy.start() } answers {
                spy.listeners.forEach { it.onAnimationStart(spy) }
                spy.listeners.forEach { it.onAnimationEnd(spy) }
            }
            every { spy.setDuration(any()) } answers { spy }
        }
    }
}

因为ViewPropertyAnimator你可以尝试类似的方法

于 2020-11-30T15:19:32.977 回答