Android 使用 mockito 测试自定义视图

Android Testing custom views with mockito

我有一个 Customview class,我想为它编写一个简单的测试。起初我想检查是否设置了 LayoutParams。

自定义视图Class

public class CustomView extends FrameLayout {

public CustomView(@NonNull Context context) {
    super(context);
    initFrameLayout();
}

public void initFrameLayout() {
    LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT);
    this.setLayoutParams(layoutParams);
}

}

CustomViewTestclass

public class CustomViewTest {

@Test
public void viewInitializedCorrectly() {
    Context context = mock(Context.class);
    CustomView customView = new CustomView(context);
    int expectedViewWidth = FrameLayout.LayoutParams.MATCH_PARENT;
    assertEquals(expectedViewWidth,  customView.getLayoutParams().width);
}

测试失败,出现 NullPointerException。我用调试器检查了该方法,我注意到 FrameLayout 对象存在但没有参数。我也应该嘲笑 CustomView.class 吗?

tests in Android 有多种不同类型。 本地单元测试 运行 在你的 IDE 在你的笔记本电脑或台式机上 仪器化单元测试 运行 在一个设备。

本地单元测试通常无法访问 Android SDK class,例如 FrameLayout。相反,您会得到这些 class 的 return 空版本。这解释了 NullPointerException

为了绕过错误,您可以手动模拟 FrameLayout 或使用类似 Robolectric 的框架,它是一个框架,提供名为 "shadows" of Android 的测试替身 class像FrameLayout.

但是,通常自定义视图不太适合单元测试,因为它们不能轻易注入模拟(因为它们被 XML 属性的 OS 膨胀)并且测试通常会退化进入 class 的反向实现。如果自定义视图确实需要 "it looks right" 之外的测试,更好的选择可能是编写 Espresso 自动化 UI 测试,它更适合这类事情。