java之 junit4单元测试Mockito的使用

一 mockito的使用

1.1 mockito介绍

Mockito是一个用于Java单元测试的mock框架,用于创建模拟对象(mock object)来替代真实对象,帮助开发者隔离外部依赖,从而专注于单元测试的逻辑,Mockito通常配合单元测试框架(如JUnit)使用。

1.2 坐标的引入

<dependency>

<groupId>org.mockito</groupId>

<artifactId>mockito-core</artifactId>

<version>4.11.0</version>

<scope>test</scope>

</dependency>

二 验证行为

2.1 验证行为

使用verify()检查mock对象的特定方法是否被调用,参数和调用次数是否符合预期

Mockito 的 verify() 用于验证模拟对象的方法是否按预期被调用 ,包括调用次数、参数匹配等。它**支持精确验证(如 times(2))、最少/最多次数(atLeast()/atMost())、未调用(never())及顺序验证(结合 InOrder)等,**确保代码执行逻辑正确。

2.2 案例

2.2.1 案例代码

复制代码
package com.ljf.services;

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

import java.util.List;

import static org.mockito.Mockito.*;

/**
 * @ClassName: MockTest
 * @Description: TODO
 * @Author: admin
 * @Date: 2025/08/17 17:19:09 
 * @Version: V1.0
 **/
@RunWith(MockitoJUnitRunner.class)
public class MockTest {
    @Mock
    List<String> strList;
    @Test
    public void test(){
        strList.add("bj");
        strList.add("sh");
        strList.add("sz");
        // 模拟调用
     // 1. 验证方法被调用【恰好一次】(默认行为)
       verify(strList).add("bj");
  strList.add("bj");
    // 2. 验证方法被调用【指定次数】
    verify(strList, times(2)).add("bj"); // 精确2次

      // 3. 验证方法【从未调用】
     verify(strList, never()).clear();

// 4. 验证【调用顺序】
 InOrder inOrder = inOrder(strList);
 inOrder.verify(strList).add("bj");
 inOrder.verify(strList).add("sh");
 inOrder.verify(strList).add("sz");
        verifyNoMoreInteractions(strList);
    }
}

2.2.2 说明

验证单次调用:verify(strList).add("bj");→ 检查 add("bj") 被调用 1 次。

验证精确次数:verify(strList, times(2)).add("bj");→ 检查 add("bj") 被调用 2 次。

验证禁止调用:verify(strList, never()).clear();→ 确保 clear() 方法从未调用。

验证调用顺序:

InOrder inOrder = inOrder(strList);

inOrder.verify(strList).add("bj");

inOrder.verify(strList).add("sh");

inOrder.verify(strList).add("sz");

三 打桩

3.1 打桩

打桩:可以模拟数据库、网络请求等复杂或不可控的操作。无论调用多少次,一旦被打桩,方法将返回指定的值。 模拟对象(Mock)的方法调用预设返回值或行为,使得测试代码可以隔离外部依赖,并控制方法的输出或异常

3.2 api说明

默认情况下,对于所有返回值的方法,mock对象将返回适当的默认值 。例如,对于intInteger返回0,对于booleanBoolean返回false,对于集合类型返回空集合,对于其他对象类型(例如字符串)返回null

参数匹配器 :使用 any()eq() 等灵活匹配参数,但需注意参数一致性(不能混用具体值和匹配器)。

覆盖规则 :最后一次打桩会覆盖之前的定义(例如多次对 mock.get(0) 打桩,以最后一次为准)。

3.3 返回值与没有返回值

  • when(...).thenX() 适用于有返回值的方法。

  • doX().when(mock).method() 适用于 void 方法。

3.4 案例

复制代码
package com.ljf.services;

import org.junit.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.when;

/**
 * @ClassName: DaZhuangTest
 * @Description: TODO
 * @Author: admin
 * @Date: 2025/08/17 17:47:42 
 * @Version: V1.0
 **/
@RunWith(MockitoJUnitRunner.class)
public class DaZhuangTest {
    @Mock
    List<String> strList;
    @Test
    public void test(){
           // 1. 创建模拟对象

     // 2. 基础打桩:返回固定值
      when(strList.get(0)).thenReturn("bj");
     assertEquals("bj", strList.get(0));

       // 3. 抛出异常
       when(strList.get(1)).thenThrow(new RuntimeException("索引错误"));
       assertThrows(RuntimeException.class, () -> strList.get(1));

   // 4. 多次调用不同返回值
     when(strList.size())
 .thenReturn(1)
.thenReturn(2);
 assertEquals(1, strList.size());
 assertEquals(2, strList.size());

// 5. 参数匹配器(如 anyInt())
 when(strList.get(anyInt())).thenReturn("default");
 assertEquals("default", strList.get(999));

// 6. Void 方法打桩(如抛出异常)
 doThrow(new IllegalStateException("清空失败")).when(strList).clear();
 assertThrows(IllegalStateException.class,strList::clear);
 }

}

未完待续.....

不用Mockito写单元测试?你可能在浪费一半时间

相关推荐
Python大数据分析@4 分钟前
python用selenium怎么规避检测?
开发语言·python·selenium·网络爬虫
ThreeAu.7 分钟前
Miniconda3搭建Selenium的python虚拟环境全攻略
开发语言·python·selenium·minicoda·python环境配置
渣哥18 分钟前
聊聊我和 ArrayList、LinkedList、Vector 的“一地鸡毛”
java
浮游本尊21 分钟前
Java学习第20天 - 性能优化与监控
java
zhangfeng113325 分钟前
R 语法高亮为什么没有,是需要安装专用的编辑软件,R语言自带的R-gui 功能还是比较简单
开发语言·r语言
纪莫1 小时前
技术面:Java并发(线程同步、死锁、多线程编排)
java·java面试⑧股
衍余未了1 小时前
k8s 内置的containerd配置阿里云个人镜像地址及认证
java·阿里云·kubernetes
叽哥1 小时前
Kotlin学习第 4 课:Kotlin 函数:从基础定义到高阶应用
android·java·kotlin
渣哥1 小时前
使用 HashMap 提高性能的小技巧
java