【问题标题】:How can I mock and test this class?我如何模拟和测试这门课?
【发布时间】:2016-09-05 13:35:20
【问题描述】:

以下是我要测试的代码。

public class Demo {

   private static final List<Pair<String, String>> mList;

   static {
     mList = new ArrayList<>();
     mList.add(new Pair<>("F0", "T1"));
     mList.add(new Pair<>("F1", "T2"));
     mList.add(new Pair<>("F2", "T3"));
   }

   public String getStr(int pos) {
     return mList.get(pos).first;
   }
}

我是一名安卓开发者。我在测试和模拟代码时遇到了一些麻烦。我使用了 mockito。 我已经尝试了一些代码来测试它,但结果不是我的预期。

1.第一次尝试

@Test
public void test(){
    Demo demo=new Demo();
    assertEquals(demo.getStr(0),"F0");
    /**
    *  java.lang.AssertionError: 
    *  Expected :null 
    *  Actual   :F0
    */
}

2.第二次尝试

@Test
public void test() {
    Demo demo = mock(Demo.class);

    doCallRealMethod().when(demo).getStr(0);
    assertEquals(demo.getStr(0), "F0");
    /**
     *  java.lang.AssertionError: 
     *  Expected :null
     *  Actual   :F0
     */
}

谁能告诉我如何通过调用真实方法来解决这个问题以制作 demo.getStr(0) == "F0"?谢谢!

============================

另一个问题与此有关

我已经尝试了另一个测试来测试android.util.Pair类,结果是“pair.first”为空,。(有androidTest和测试目录,我把它放在测试包中。它有影响吗结果?)

import android.util.Pair;

import org.junit.Test;
import org.mockito.Mockito;

import static org.junit.Assert.assertEquals;

public class DemoTest {
    @Test
    public  void test1(){
        Pair<String,String> pair=new Pair("First","Second");
        assertEquals("First",pair.first);
        //pair.first was null,why?
    }

    @Test
    public void test2(){
        Pair<String,String> pair= Mockito.spy(Pair.class);
        assertEquals("First",pair.first);
        //pair.first was null also,why?
    }
}

为什么简单的代码在真实的android环境下是正确的,但在测试中却失败了?

【问题讨论】:

  • 为什么结果总是空?
  • 在第一个实现中,您甚至没有使用 mockito。看来Pair类的first字段确实是null
  • @Apokralipsa 但是在第二个实现中它仍然是空的,为什么?这让我困扰了很久。你能给我一个正确的例子吗?我应该使用 PowerMock,因为该字段是静态的和最终的?

标签: android unit-testing mockito


【解决方案1】:

我也有同样的问题。一个月前我也遇到了 TextUtils 类的问题。

我将此报告给 jUnit,但他们告诉我问题出在 android 包上,因为在单元测试环境中您无权访问特定于平台的类

对于这种情况,您可以使用此包。这对我有用

import android.support.v4.util.Pair;

【讨论】:

    【解决方案2】:

    您第一次尝试的问题是,公共字段“first”实际上为空。

    Pair 类是来自“javafx.util”包还是自定义实现? 是不是忘记了“Pair”类的构造函数中的“this.first = first”之类的东西?

    我还建议更改以下行:

    assertEquals(demo.getStr(0),"F0");

    assertEquals("F0", demo.getStr(0));

    以便正确打印错误。

    您的第二次尝试没有任何意义。模拟您要测试的课程有什么意义?

    我认为第二个例子和第一个例子有同样的问题。 Pair.first 永远不会设置。如果你解决了这个问题,它也应该可以工作(未经测试)。

    【讨论】:

    • Pair 类是 android.util.Pair。它具有设置第一个和第二个字段的构造函数。我已将代码更改为“assertEquals("F0", demo.getStr(0));”,但它也返回 null。
    【解决方案3】:

    来自 Google 的 Android 工具网站:


    “方法...未模拟。”

    用于运行单元测试的 android.jar 文件不包含任何实际代码 - 由真实设备上的 Android 系统映像提供。 相反,所有方法都会抛出异常(默认情况下)。这是为了确保您的单元测试只测试您的代码,而不依赖于 Android 平台的任何特定行为(您没有明确模拟,例如使用 Mockito)。


    那么我们该如何解决呢?

    换句话说。如果您需要一个默认的 android 类才能正常工作,您要么必须从单独的存储库中包含它,要么自己实现它。

    以 Android 的 Pair 类为例。您可以改用android.support.v4.util.Pair

    要访问此类,您可以在 build.gradle 或依赖文件中包含 com.android.support:support-compat:27.0.0

    如果你不使用 Gradle,你可以复制这个文件的实现并使用它来代替官方的。或者你可以尝试从这个旧版本https://mvnrepository.com/artifact/com.google.android/support-v4/r7下载.jar文件(我没有测试它是否有效)

    【讨论】:

      【解决方案4】:

      另一种方法(基于this)是在app/src/test/java/android/util/Pair.java 中创建类并从Android 实现中复制代码。

      这样你就不需要额外的依赖了。 (复制后可能会出现与实现更改相关的问题,但依赖项也可能变得陈旧。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多