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);
相关推荐
学长毕设20 分钟前
基于springboot的食品仓库管理系统
java·spring boot·后端
步行cgn1 小时前
FormHttpMessageConverter 详解:Spring MVC 中表单数据的读写转换器
java·spring·mvc
龙亘川1 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
金銀銅鐵1 小时前
[Java] 用 CLI 展示 EnumMap 增删键值对时的内部变化
java·源码·ai编程
秋天的怀念_David1 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Raas1002 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
niucloud-admin2 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php
霸道流氓气质3 小时前
智能客服组件:分层意图识别、RAG Advisor 与人工转接状态机的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
captain3763 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis
心中有你02144 小时前
Java实现Dijkstra最短路径算法(邻接表 + 优先队列)
java·数据库·算法