Springboot+Mockito简单使用单元测试

1、添加单元测试依赖

本文使用的springboot版本是2.7.18版本,并已集成Mockito 4.5.1版本。

java 复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
        </dependency>

2、添加两个测试类

TestBeanA类:

java 复制代码
@Service
public class TestBeanA {
    @Autowired
    private TestBeanB testBeanB;

    public int sayHello(String s){
        String hello = testBeanB.getHello(s);
        System.out.println("A:" + hello);
        return 1;
    }
}

TestBeanB类:

java 复制代码
@Service
public class TestBeanB {

    public String getHello(String s){
        System.out.println("B:" + s);
        return "hello world";
    }
}

3、单元测试类

java 复制代码
@ExtendWith(MockitoExtension.class)
public class MockTest {

    // 自动把testBeanB注入到testBeanA
    @InjectMocks
    TestBeanA testBeanA;

    // 模拟对象,方法不会执行
    @Mock
    // 真实对象,方法会执行
//    @Spy
    TestBeanB testBeanB;

    @Test
    public void test() {
        when(testBeanB.getHello("mock")).thenReturn("Mock Hello");
        System.out.println(testBeanA.sayHello("mock"));
        verify(testBeanB, times(1)).getHello(anyString());
        verify(testBeanB, never()).getHello("moc");

    }
}

4、执行结果

java 复制代码
A:Mock Hello
1

5、主要注解说明

@ExtendWith (MockitoExtension.class)

作用是让 JUnit5 测试框架整合 Mockito,自动管理 Mock 对象、依赖注入、生命周期。

无需手动调用 Mockito.initMocks(this),测试类中标记的对象自动生成:

  • @Mock:生成模拟对象,所有方法默认返回空值 /null;
  • @Spy:基于真实对象创建间谍,真实方法会执行;
  • @InjectMocks:自动把上面的 Mock/Spy 注入到被测试类的成员变量(构造器 /setter/ 字段注入)。

示例:

java 复制代码
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
    // 自动mock
    @Mock
    private UserMapper userMapper;

    // 自动把userMapper注入UserService
    @InjectMocks
    private UserService userService;

    @Test
    void testGetUser() {
        when(userMapper.selectById(1L)).thenReturn(new User());
        User user = userService.getById(1L);
        assertNotNull(user);
    }
}

verify(mock对象)

verify(mock对象) 用于校验某个 Mock 对象的指定方法是否被调用、调用次数、调用参数。 单元测试中用来断言:业务代码逻辑确实执行了依赖的 DAO / 工具类方法,验证流程符合预期。

默认 verify(mock) = 校验该方法被调用至少 1 次

java 复制代码
// 1. 无次数:校验方法执行过一次及以上
verify(userMapper).selectById(1L);

// 2. 精确次数校验
verify(userMapper, times(1)).selectById(1L);

// 3. 从未调用
verify(userMapper, never()).deleteById(any());

// 4. 最少、最多调用
verify(userMapper, atLeast(2)).listAll();
verify(userMapper, atMost(3)).listAll();

Mockito 参数匹配器:eq ()、any ()、anyString ()

when () 打桩、verify () 校验时,用来匹配方法入参,分为精准匹配、模糊匹配两类; 所有匹配器不能混用普通字面量,要么全匹配器,要么全常量。

  • eq(值):精准等值匹配,混合 any 时必用;
  • any(Class):匹配任意该类型非 null 对象;
  • anyString()/anyLong:基础类型专用模糊匹配;
  • 只要用了任意模糊匹配器,全部参数都要用匹配器包裹。

示例:

java 复制代码
// 精准匹配参数必须等于 1L
when(mapper.selectById(eq(1L))).thenReturn(user);
verify(mapper).selectById(eq(1L));

等价写法(简单参数可省略 eq):

java 复制代码
when(mapper.selectById(1L)).thenReturn(user);
相关推荐
鹿角片ljp29 分钟前
KV Cache 解析
java·算法
captain3761 小时前
网络原理(9)-数据链路层
java·网络协议·java-ee
惊讶的猫1 小时前
意图识别置信度和检索重排的分数
java
caoerzhong2 小时前
仓库管理数字化趋势解读:JeeWMS 开源 Java WMS 视角下的五个演进方向
java·开源
程序员JerrySUN2 小时前
Jetson Edge AI 实战01:Nano、Xavier、Orin 怎么选?Jetson 硬件选型详解【视频讲解】
java·数据库·redis·安全·mybatis
Joy T3 小时前
Spring AI 2.0 Agent 进阶:Memory、State 与 Context Engineering 常见技术全景
java·人工智能·后端·spring·agent入门·agent state
估值探索者3 小时前
【Python量化系统工程化 #08】关了 SSH 就停?systemd 让脚本开机自启 + 异常自动拉起
java·c++·人工智能·分类·数据挖掘
天若有情6733 小时前
C++花式魔改!手写头文件复刻Java语法,彻底打破编码思维定式
java·c++·语言做语言·jac++
西峰u5 小时前
Java单例模式|从基础到多线程安全
java·java单例模式