单元测试—Mockito学习


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

单元测试 – Mockito入门

1、mock()方法

org.mockito.Mockito 的 mock 方法可以模拟类和接口,以下代码演示直接在Test方法中对类和接口进行Mock

@Test
public void test() {
    List mockList = mock(List.class);
    // mock对象的方法返回值默认都是返回类型的默认值。例如返回类型是int,默认返回值是0;类型是一个类,默认返回值是null。
    Assert.assertEquals(0, mockList.size());
    Assert.assertEquals(null, mockList.get(0));
    // 调用 mock 对象的写方法,是没有效果的
    mockList.add("a");
    // 没有指定 size() 方法返回值,这里结果是默认值
    Assert.assertEquals(0, mockList.size());
    // 没有指定 get(0) 返回值,这里结果是默认值
    Assert.assertEquals(null, mockList.get(0));

    // 指定 get(0)时返回 a
    when(mockList.get(0)).thenReturn("a");
    // 没有指定 size() 方法返回值,这里结果是默认值
    Assert.assertEquals(0, mockList.size());
    // 因为上面指定了 get(0) 返回 a,所以这里会返回 a
    Assert.assertEquals("a", mockList.get(0));
    // 没有指定 get(1) 返回值,这里结果是默认值
    Assert.assertEquals(null, mockList.get(1));

    // 指定 size()返回123
    when(mockList.size()).thenReturn(123);
    Assert.assertEquals(123, mockList.size());
}

2、@Mock 注解

@Mock 注解可以理解为对 mock 方法的一个替代。使用该注解时,要使用MockitoAnnotations.openMocks 方法,让注解生效。所以相对于1中的单测,会变成如下的形式。

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.List;
import static org.mockito.Mockito.when;

public class Mocktio {
    @Mock
    private List mockList;

    @Before
    public void setUp() {
        MockitoAnnotations.openMocks(this);
    }

    @Test
    public void test() {

        // mock 对象的方法的返回值默认都是返回类型的默认值。例如返回类型是一个类,默认返回值是 null。
        Assert.assertEquals(0, mockList.size());
        Assert.assertEquals(null, mockList.get(0));
        // 调用 mock 对象的写方法,是没有效果的
        mockList.add("a");
        // 没有指定 size() 方法返回值,这里结果是默认值
        Assert.assertEquals(0, mockList.size());
        // 没有指定 get(0) 返回值,这里结果是默认值
        Assert.assertEquals(null, mockList.get(0));

        // 指定 get(0)时返回 a
        when(mockList.get(0)).thenReturn("a");
        // 没有指定 size() 方法返回值,这里结果是默认值
        Assert.assertEquals(0, mockList.size());
        // 因为上面指定了 get(0) 返回 a,所以这里会返回 a
        Assert.assertEquals("a", mockList.get(0));
        // 没有指定 get(1) 返回值,这里结果是默认值
        Assert.assertEquals(null, mockList.get(1));

        // 指定 size()返回123
        when(mockList.size()).thenReturn(123);
        Assert.assertEquals(123, mockList.size());
    }
}

3、MockitoJUnitRunner

MockitoAnnotations.initMocks 的一个替代方案是使用 MockitoJUnitRunner ,具体的代码变形为

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import java.util.List;

import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class Mocktio {
    @Mock
    private List mockList;

    @Test
    public void test() {

        // mock 对象的方法的返回值默认都是返回类型的默认值。例如返回类型是一个类,默认返回值是 null。
        Assert.assertEquals(0, mockList.size());
        Assert.assertEquals(null, mockList.get(0));
        // 调用 mock 对象的写方法,是没有效果的
        mockList.add("a");
        // 没有指定 size() 方法返回值,这里结果是默认值
        Assert.assertEquals(0, mockList.size());
        // 没有指定 get(0) 返回值,这里结果是默认值
        Assert.assertEquals(null, mockList.get(0));

        // 指定 get(0)时返回 a
        when(mockList.get(0)).thenReturn("a");
        // 没有指定 size() 方法返回值,这里结果是默认值
        Assert.assertEquals(0, mockList.size());
        // 因为上面指定了 get(0) 返回 a,所以这里会返回 a
        Assert.assertEquals("a", mockList.get(0));
        // 没有指定 get(1) 返回值,这里结果是默认值
        Assert.assertEquals(null, mockList.get(1));

        // 指定 size()返回123
        when(mockList.size()).thenReturn(123);
        Assert.assertEquals(123, mockList.size());
    }
}

4、参数匹配

// 可以使用 Mockito.anyInt() 匹配所有类型为 int 的参数
when(mockList.get(anyInt())).thenReturn("a");

Assert.assertEquals("a", mockList.get(0));
Assert.assertEquals("a", mockList.get(1));

mockito 有多种匹配函数,部分如下:

函数名 匹配类型
any() 所有对象类型
anyInt() 基本类型 int、非 null 的 Integer 类型
anyChar() 基本类型 char、非 null 的 Character 类型
anyShort() 基本类型 short、非 null 的 Short 类型
anyBoolean() 基本类型 boolean、非 null 的 Boolean 类型
anyDouble() 基本类型 double、非 null 的 Double 类型
anyFloat() 基本类型 float、非 null 的 Float 类型
anyLong() 基本类型 long、非 null 的 Long 类型
anyByte() 基本类型 byte、非 null 的 Byte 类型
anyString() String 类型(不能是 null)
anyList() List<T> 类型(不能是 null)
anyMap() Map<K, V>类型(不能是 null)
anyCollection() Collection<T>类型(不能是 null)
anySet() Set<T>类型(不能是 null)
any(Class<T> type) type类型的对象(不能是 null)
isNull() null
notNull() 非 null

5、@Spy 注解

spy 和 mock不同,不同点是:

  • spy 的参数是对象示例,mock 的参数是 class。
  • 被 spy修饰的对象,调用其方法时默认会走真实方法。mock 对象不会。
@RunWith(MockitoJUnitRunner.class)
public class Mocktio {
    @Mock
    private ExampleService spyExampleService;

    @Test
    public void test_spy() {

        //Assert.assertEquals(3, spyExampleService.add(1, 2));

        when(spyExampleService.add(1, 2)).thenReturn(10);
        Assert.assertEquals(10, spyExampleService.add(1, 2));

    }

    class ExampleService {

        int add(int a, int b) {
            System.out.println("方法调用被执行");
            return a+b;
        }

    }
}

// Console打印为空
//如果我们将@Mock注解替换为@Spy 去除单行注释//Assert.assertEquals(3, spyExampleService.add(1, 2)); COnsole打印:
方法调用被执行
方法调用被执行

文章作者: WangQingLei
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 WangQingLei !
  目录