Mockito 指南

Mockito 是一个模拟测试框架,主要功能是在单元测试中模拟类/对象的行为。
所有文章
入门 引入依赖包 使用 mock 方法模拟类和接口 使用 @Mock 注解 mock 泛型类、泛型接口 参数匹配 参数匹配顺序 spy 和 @Spy 注解 @InjectMocks 注解注入 mock 对象 使用 thenReturn 设置方法的返回 使用 thenThrow 让方法抛出异常 使用then、thenAnswer 自定义方法处理逻辑 使用 doReturn 设置方法的返回值 使用 doThrow 让方法抛出异常 使用 doAnswer 自定义方法处理逻辑 使用 doNothing 让 void 函数什么都不做 使用 MockitoJUnitRunner 运行 JUnit 测试 使用 MockitoAnnotations.initMocks 让 @Mock 等注解生效 使用 reset 重置对象 使用 thenCallRealMethod 调用 spy 对象的真实方法 使用 verify 校验是否发生过某些操作 使用 mockingDetails 判断对象是否为 mock对象、spy 对象 链式调用 测试隔离 使用 PowerMock 让 Mockito 支持静态方法 临时 mock 对象

Mocktio 入门


Mockito 是一个模拟测试框架。主要功能是模拟类/对象的行为。

Mockito 一般用于控制调用外部的返回值,让我们只关心和测试自己的业务逻辑。

我们看一个示例:

package demo;

import java.util.Random;

public class HttpService {

    public int queryStatus() {
        // 发起网络请求,提取返回结果
        // 这里用随机数模拟结果
        return new Random().nextInt(2);
    }

}
package demo;

public class ExampleService {

    private HttpService httpService;

    public void setHttpService(HttpService httpService) {
        this.httpService = httpService;
    }

    public String hello() {
        int status = httpService.queryStatus();
        if (status == 0) {
            return "你好";
        }
        else if (status == 1) {
            return "Hello";
        }
        else {
            return "未知状态";
        }
    }

}

使用示例:

package demo;

public class Main {

    public static void main(String[] args) {
        HttpService realHttpService = new HttpService();
        ExampleService exampleService = new ExampleService();
        exampleService.setHttpService(realHttpService);
        System.out.println( exampleService.hello() );
    }
}

每次运行的结果可能不同,可能是你好,也可能是Hello

现在我们引入 mockito。如果是用 gradle 构建 gradle 项目,加入以下依赖:

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    testCompile group: 'org.mockito', name: 'mockito-core', version: '2.25.1'
}

注意,我们引入了 junit 来编写断言。断言是测试的核心。

整个项目结构如下:

├── build.gradle
├── settings.gradle
└── src
    ├── main
    │   ├── java
    │   │   └── demo
    │   │       ├── HttpService.java
    │   │       ├── Main.java
    │   │       └── ExampleService.java
    │   └── resources
    └── test
        ├── java
        │   └── demo
        │       └── ExampleServiceTest.java
        └── resources

其中 test 目录下的 ExampleServiceTest 类,是我们新增的测试类:

package demo;

import org.junit.Assert;
import org.junit.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;


public class ExampleServiceTest {

    @Test
    public void test() {
        // 创建mock对象
        HttpService mockHttpService = mock(HttpService.class);
        // 使用 mockito 对 queryStatus 方法打桩
        when(mockHttpService.queryStatus()).thenReturn(1);
        // 调用 mock 对象的 queryStatus 方法,结果永远是 1
        Assert.assertEquals(1, mockHttpService.queryStatus());

        ExampleService exampleService = new ExampleService();
        exampleService.setHttpService(mockHttpService);
        Assert.assertEquals("Hello", exampleService.hello() );
    }

}

我们通过 mock 函数生成了一个 HttpService 的 mock 对象(这个对象是动态生成的)。

通过 when .. thenReturn 指定了当调用 mock对象的 queryStatus 方法时,返回 1 ,这个叫做打桩

然后将 mock 对象注入到 exampleService 中,exampleService.hello() 的返回永远是 Hello


( 本文完 )

目录