1、添加依赖

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>5.20.0</version>
    <scope>test</scope>
</dependency>

<!-- 如果使用 JUnit 5 -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>5.20.0</version>
    <scope>test</scope>
</dependency>

2、测试类写法(标准模板)

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

// 开启 Mockito
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {

    // 模拟依赖(假对象)
    @Mock
    private UserDao userDao;

    // 要测试的类,自动注入 mock
    @InjectMocks
    private UserService userService;

    @Test
    void testGetUser() {
        // 1. 模拟返回值
        User mockUser = new User(1L, "mock-name");
        when(userDao.getById(1L)).thenReturn(mockUser);

        // 2. 调用业务方法
        User result = userService.getById(1L);

        // 3. 断言
        assertEquals("mock-name", result.getName());

        // 4. 验证方法调用
        verify(userDao).getById(1L);
    }
}

3、Mockito 5.20.0 核心功能

模拟返回任意值

// 固定值
when(userDao.getById(1L)).thenReturn(new User(1L, "张三"));

// 多个返回(依次返回)
when(userDao.getById(1L)).thenReturn(u1, u2, u3);

thenAnswer

        动态回调应答,可根据实际入参动态计算返回值、自定义逻辑,比固定thenReturn灵活。

@Test
void testThenAnswerParam() {
    when(userDao.getById(anyLong())).thenAnswer(invocation -> {
        // 获取实际传入的参数
        Long id = invocation.getArgument(0);
        // 根据参数动态返回
        return new User(id, "动态用户"+id);
    });

    User u1 = userService.getById(1L);
    User u2 = userService.getById(2L);
    assertEquals("动态用户1", u1.getName());
    assertEquals("动态用户2", u2.getName());
}

模拟抛出异常

// 有返回值方法
when(userDao.getById(null)).thenThrow(IllegalArgumentException.class);

// void 方法(5.x 推荐写法)
doThrow(RuntimeException.class).when(userDao).delete(anyLong());

参数匹配器(万能写法)

// 任意 Long
when(userDao.getById(anyLong())).thenReturn(user);

// 任意对象
when(userDao.save(any(User.class))).thenReturn(true);

// 不为 null
when(userDao.getById(notNull())).thenReturn(user);

验证调用次数(非常常用)

// 调用 1 次
verify(userDao).getById(1L);

// 调用 2 次
verify(userDao, times(2)).getById(1L);

// 从未调用
verify(userDao, never()).delete(any());

捕获参数(拿到传入的对象)

import org.mockito.ArgumentCaptor;

@Test
void testCapture() {
    ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class);

    userService.save(new User(1L, "test"));

    verify(userDao).save(captor.capture());
    User saved = captor.getValue();

    assertEquals(1L, saved.getId());
}

4、Mockito 5 最强特性:原生支持 静态方法 / 构造方法 /final 类

模拟静态方法(如 UUID、LocalDateTime)

@Test
void testStatic() {
    try (var mocked = mockStatic(UUID.class)) {
        mocked.when(UUID::randomUUID)
               .thenReturn(UUID.fromString("1-1-1-1-1"));

        assertEquals("1-1-1-1-1", UUID.randomUUID().toString());
    }
}

模拟构造方法(new 对象时返回 mock)

@Test
void testConstructor() {
    try (var mocked = mockConstruction(ArrayList.class)) {
        List<String> list = new ArrayList<>(); // 自动变成 mock

        when(list.size()).thenReturn(100);
        assertEquals(100, list.size());
    }
}

模拟 final 类 /final 方法(5.x 原生支持)

@Mock
private FinalUserDao finalUserDao; // final 类也能 mock

@Test
void testFinal() {
    when(finalUserDao.get(anyLong())).thenReturn(new User());
}

5、Spy:部分真实、部分模拟

@Spy
private UserDao userDao; // 真实对象

@Test
void testSpy() {
    // 只模拟这一个方法
    when(userDao.getById(1L)).thenReturn(new User(1L, "spy"));

    // 模拟结果
    User u1 = userDao.getById(1L);

    // 真实方法
    User u2 = userDao.getById(2L);
}

6、5.20.0 严格模式(默认更严格,避免烂测试)

// 宽松模式:允许没用到的 stub(不报错)
@Mock(strictness = Strictness.LENIENT)
private UserDao userDao;

7、最容易踩的坑

  • 不要再用 PowerMock → Mockito 5 已原生支持静态、构造、final
  • 不要引入 mockito-inline → 5.x 已内置,加了会冲突
  • 必须 Java 11+
  • 静态 / 构造模拟必须用 try-with-resources 自动关闭
  • void 方法必须用 doThrow() / doNothing()

8、一句话总结

  • @Mock:创建假对象
  • @InjectMocks:把假对象注入测试类
  • when(…).thenReturn(…):模拟返回
  • verify(…):验证调用
  • mockStatic / mockConstruction:模拟静态 / 构造(5.x 最强功能)
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐