如何将Mockito设置为Android单元测试的模拟类

Sur*_*gch 4 android unit-testing mockito

如果我做一个简单的测试用例

@Test
public void myTest() throws Exception {
    Spanned word = new SpannedString("Bird");
    int length = word.length();
}
Run Code Online (Sandbox Code Playgroud)

抛出异常

java.lang.RuntimeException:未模拟android.text.SpannableStringInternal中的方法长度.有关详细信息,请参阅 http://g.co/androidstudio/not-mocked.

这在上面的链接中解释为

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

那么你如何在Android项目中设置Mockito以模拟这样的类?

我想学习,所以我将在Q&A风格下添加我的答案.

Sur*_*gch 10

在您的项目中设置Mockito并不困难.步骤如下.

1.添加Mockito依赖项

假设您正在使用jcenter存储库(Android Studio中的默认存储库),请将以下行添加到dependencies应用程序的build.gradle文件块中:

testImplementation "org.mockito:mockito-core:2.8.47"
Run Code Online (Sandbox Code Playgroud)

您可以将版本号更新为最新的Mockito版本.

它应该看起来像这样:

dependencies {
    // ...
    testImplementation 'junit:junit:4.12'
    testImplementation "org.mockito:mockito-core:2.8.47"
}
Run Code Online (Sandbox Code Playgroud)

2.将Mockito导入您的测试类

通过导入静态类,您可以使代码更具可读性(即Mockito.mock(),您可以使用mock())而不是调用.

import static org.mockito.Mockito.*;
Run Code Online (Sandbox Code Playgroud)

3.在测试中模拟对象

你需要做三件事来模拟对象.

  1. 使用创建类的模拟mock(TheClassName.class).
  2. 告诉模拟类要为您需要调用的任何方法返回什么.你用when和做这个thenReturn.
  3. 在测试中使用模拟方法.

这是一个例子.真正的测试可能会使用模拟值作为测试任何内容的某种输入.

public class MyTestClass {

    @Test
    public void myTest() throws Exception {
        // 1. create mock
        Spanned word = mock(SpannedString.class);

        // 2. tell the mock how to behave
        when(word.length()).thenReturn(4);

        // 3. use the mock
        assertEquals(4, word.length());
    }
}
Run Code Online (Sandbox Code Playgroud)

进一步研究

Mockito还有很多东西.请参阅以下资源以继续学习.

或试试这个......

学习模拟很好,因为它很快并隔离了被测试的代码.但是,如果您正在测试一些使用Android API的代码,则可能更容易使用检测测试而不是单元测试.看到这个答案.