Mockit框架测试使用示例

环境

http://site.mockito.org/

// https://mvnrepository.com/artifact/org.mockito/mockito-all
testCompile group: 'org.mockito', name: 'mockito-all', version: '1.10.19'

<dependency>
    <groupId>org.mockitogroupId>
    <artifactId>mockito-allartifactId>
    <version>1.10.19version>
    <scope>testscope>
dependency>
import static org.mockito.Mockito.*;

验证

class Clasz {
}

@Test
public void test01() {
    //创建Mock对象
    List lists = mock(List.class);

    Clasz clasz = new Clasz();//创建对象

    //执行对象的某个方法
    lists.add(clasz);

    //判断是否执行了某个方法
    verify(lists).add(clasz);
}
  • 使用mock方法创建的对象具有记忆方法被调用的能力
  • verify方法用于判断模拟的对象某个方法是否被调用
  • 参数列表必须相同,传入的数据也必须相同
  • 基本数据类型值必须相同,引用数据类型对象必须完全一致且不能发生改变

打桩

@Test
public void test02() {
    //创建Mock对象
    List list = mock(ArrayList.class);

    //确保交互(interaction)操作不会执行在mock对象上
    list.add("张三");
    System.out.println(list.size());//0
    System.out.println(list.get(0));//null
    System.out.println(list.get(1));//null

    //测试桩,打桩
    when(list.get(1)).thenReturn("李四");

    //调用
    System.out.println(list.size());//0
    System.out.println(list.get(0));//null
    System.out.println(list.get(1));//李四

    when(list.add("王五")).thenReturn(true);

    System.out.println(list.add("王五"));//true
    System.out.println(list.add("赵六"));//false
}
  • 可以使用任何不被final修饰的可访问的类做mock对象
  • 使用mock方法创建的对象不会被交互操作影响
  • when的作用是打桩,当触发指定的方法时(参数列表和入参数据必须完全一致),执行预先指定好的方法

当入参类型为Object时,可能会因为HashCode不相同使参数列表入参不同导致无法捕获,可以使用isA(class)代替实际入参

Mockito.when(userDao.save(Mockito.isA(User.class))).thenReturn(user);

连续打桩

@Test
public void test08() {
    List list = mock(ArrayList.class);

    when(list.get(0)).thenReturn("张三","李四","王五");

    //连续的打桩
    System.out.println(list.get(0));//张三
    System.out.println(list.get(0));//李四
    System.out.println(list.get(0));//王五
}

重写Answer接口的answer方法

传入InvocationOnMock对象,封装了调用的方法的所有信息

@Test
public void test03() {
    //创建Mock对象
    List list = mock(ArrayList.class);

    //打桩
    when(list.get(0)).then(invocation -> "张三");

    System.out.println(list.size());//0
    System.out.println(list.get(0));//张三
}

InvocationOnMock回调测试桩对象

@Test
public void test09() {
    List list = mock(ArrayList.class);

    when(list.add(anyString())).thenAnswer(invocation -> {
        Object[] args = invocation.getArguments();
        Object mock = invocation.getMock();
        Method method = invocation.getMethod();
        System.out.println("参数: " + args[0] + "\n描述:" + mock + "\n方法:" + method + "\n");
        /*
        参数: 张三
        描述:Mock for ArrayList, hashCode: 90320863
        方法:public boolean java.util.ArrayList.add(java.lang.Object)
         */
        return true;
    });

    System.out.println(list.add("张三"));
}

异常

取代stubVoid()用于处理void的方法返回

@Test
public void test05(){

    List list = mock(ArrayList.class);

    doThrow(RuntimeException.class).when(list).clear();

    list.clear();//java.lang.RuntimeException
}

次数

@Test
public void test04(){

    List list = mock(ArrayList.class);

    list.add("一次");

    list.add("两次");
    list.add("两次");

    list.add("三次");
    list.add("三次");
    list.add("三次");


    // 下面的两个验证函数效果一样,因为verify默认验证的就是times(1)
    verify(list).add("一次");
    verify(list, times(1)).add("一次");

    // 验证具体的执行次数
    verify(list, times(2)).add("两次");
    verify(list, times(3)).add("三次");

    // 使用never()进行验证,never相当于times(0)
    verify(list, never()).add("零次");

    // 使用atLeast()/atMost()
    verify(list, atLeastOnce()).add("三次");//至少一次
    verify(list, atLeast(1)).add("三次");//最少1次
    verify(list, atMost(5)).add("三次");//最多5次

    list.clear();//冗余的调用,未做验证和处理
    verifyNoMoreInteractions(list);
}

指定顺序

@Test
public void test06(){
    List list = mock(ArrayList.class);

    list.add("第一步");//1
    list.add("第三步");//2,没有4会验证失败
    list.add("第二步");//3
    list.add("第三步");//4

    //创建Inorder对象
    InOrder inOrder = inOrder(list);

    inOrder.verify(list).add("第一步");
    inOrder.verify(list).add("第二步");
    inOrder.verify(list).add("第三步");
}
  • 必须保持打桩的方法是按照inOrder指定的顺序执行
  • inOrder的中间可以穿插重复多个方法

使用注解创建

@Mock
private Set set;

@Test
public void test07() {
    //在运行测试函数之前需要被调用
    MockitoAnnotations.initMocks(this);

    set.add("张三");
    System.out.println(set.size());//0
}

你可能感兴趣的:(测试)