51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 1911|回复: 0
打印 上一主题 下一主题

[原创] Mockit框架测试使用示例

[复制链接]
  • TA的每日心情
    擦汗
    2022-8-30 09:02
  • 签到天数: 2 天

    连续签到: 2 天

    [LV.1]测试小兵

    跳转到指定楼层
    1#
    发表于 2019-3-22 15:25:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    环境
    1. // https://mvnrepository.com/artifact/org.mockito/mockito-all
    2. testCompile group: 'org.mockito', name: 'mockito-all', version: '1.10.19'
    复制代码
    1. <!-- https://mvnrepository.com/artifact/org.mockito/mockito-all -->
    2. <dependency>
    3.     <groupId>org.mockito</groupId>
    4.     <artifactId>mockito-all</artifactId>
    5.     <version>1.10.19</version>
    6.     <scope>test</scope>
    7. </dependency>
    复制代码
    1. import static org.mockito.Mockito.*;
    复制代码

    验证
    1. class Clasz {
    2. }

    3. @Test
    4. public void test01() {
    5.     //创建Mock对象
    6.     List<Clasz> lists = mock(List.class);

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

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

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

    打桩
    1. @Test
    2. public void test02() {
    3.     //创建Mock对象
    4.     List<String> list = mock(ArrayList.class);

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

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

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

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

    17.     System.out.println(list.add("王五"));//true
    18.     System.out.println(list.add("赵六"));//false
    19. }
    复制代码
    可以使用任何不被final修饰的可访问的类做mock对象
    使用mock方法创建的对象不会被交互操作影响
    when的作用是打桩,当触发指定的方法时(参数列表和入参数据必须完全一致),执行预先指定好的方法
    当入参类型为Object时,可能会因为HashCode不相同使参数列表入参不同导致无法捕获,可以使用isA(class)代替实际入参


    1. Mockito.when(userDao.save(Mockito.isA(User.class))).thenReturn(user);
    复制代码

    连续打桩
    1. @Test
    2. public void test08() {
    3.     List<String> list = mock(ArrayList.class);

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

    5.     //连续的打桩
    6.     System.out.println(list.get(0));//张三
    7.     System.out.println(list.get(0));//李四
    8.     System.out.println(list.get(0));//王五
    9. }
    复制代码

    重写Answer接口的answer方法

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

    1. @Test
    2. public void test03() {
    3.     //创建Mock对象
    4.     List<String> list = mock(ArrayList.class);

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

    7.     System.out.println(list.size());//0
    8.     System.out.println(list.get(0));//张三
    9. }
    复制代码

    InvocationOnMock回调测试桩对象
    1. @Test
    2. public void test09() {
    3.     List<String> list = mock(ArrayList.class);

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

    16.     System.out.println(list.add("张三"));
    17. }
    复制代码

    异常

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

    1. @Test
    2. public void test05(){

    3.     List<String> list = mock(ArrayList.class);

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

    5.     list.clear();//java.lang.RuntimeException
    6. }
    复制代码

    次数
    1. @Test
    2. public void test04(){

    3.     List<String> list = mock(ArrayList.class);

    4.     list.add("一次");

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

    7.     list.add("三次");
    8.     list.add("三次");
    9.     list.add("三次");


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

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

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

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

    22.     list.clear();//冗余的调用,未做验证和处理
    23.     verifyNoMoreInteractions(list);
    24. }
    复制代码

    指定顺序
    1. @Test
    2. public void test06(){
    3.     List<String> list = mock(ArrayList.class);

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

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

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

    使用注解创建
    1. @Mock
    2. private Set<String> set;

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

    7.     set.add("张三");
    8.     System.out.println(set.size());//0
    9. }
    复制代码



    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-4-20 07:46 , Processed in 0.064416 second(s), 22 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表