在 Java 单元测试的世界里,有些依赖就像难以驯服的野马 —— 数据库连接时好时坏,第三方接口响应慢吞吞。而Mockito这位模拟大师,能凭空创造出温顺听话的 "假对象",让你的测试不再受外部依赖的牵制,跑得又快又稳。
快速创建模拟对象
只需一个注解,Mockito 就能变出你需要的依赖对象,比魔术师变鸽子还快:
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 java.util.List;
import static org.mockito.Mockito.*;// 启用Mockito扩展
@ExtendWith(MockitoExtension.class)
public class OrderServiceTest {// 模拟一个List对象@Mockprivate List<String> mockList;// 将模拟对象注入到测试目标@InjectMocksprivate OrderService orderService;@Testpublic void testMock() {// 指挥模拟对象如何"表演"when(mockList.get(0)).thenReturn("第一个元素");when(mockList.size()).thenReturn(10);// 调用模拟对象System.out.println(mockList.get(0)); // 输出"第一个元素"System.out.println(mockList.size()); // 输出10}
}
验证方法调用行为
Mockito 不仅能模拟对象,还能像侦探一样记录所有调用行为,帮你确认代码是否按预期执行:
@Test
public void testVerify() {// 执行操作mockList.add("test");mockList.add("test");mockList.get(0);// 验证调用次数verify(mockList, times(2)).add("test"); // 确认add("test")被调用2次verify(mockList, atLeastOnce()).get(0); // 确认get(0)至少被调用1次verify(mockList, never()).clear(); // 确认clear()从未被调用
}
模拟异常场景
测试异常处理逻辑时,Mockito 能让模拟对象按指令抛出异常,就像按下了故障开关:
@Test
public void testException() {// 让get(1)调用时抛出异常when(mockList.get(1)).thenThrow(new IndexOutOfBoundsException());try {mockList.get(1);} catch (IndexOutOfBoundsException e) {// 预期的异常被捕获}
}
间谍模式:部分模拟
有时你需要保留真实对象的部分功能,只替换特定方法,这时间谍模式就派上用场了:
@Test
public void testSpy() {// 创建真实ArrayList的间谍List<String> realList = new ArrayList<>();List<String> spyList = spy(realList);// 真实方法会被执行spyList.add("hello");System.out.println(spyList.size()); // 输出1// 特定方法被模拟when(spyList.get(0)).thenReturn("mock hello");System.out.println(spyList.get(0)); // 输出"mock hello",而非真实的"hello"
}
参数匹配器:灵活匹配
面对复杂参数,Mockito 的参数匹配器能像万能钥匙一样适配各种情况:
@Test
public void testArgumentMatcher() {// 匹配任何字符串参数when(mockList.contains(anyString())).thenReturn(true);// 匹配长度大于3的字符串when(mockList.add(argThat(s -> s.length() > 3))).thenReturn(true);System.out.println(mockList.contains("test")); // 输出trueSystem.out.println(mockList.add("short")); // 输出false(长度不大于3)System.out.println(mockList.add("longer")); // 输出true(长度大于3)
}
Mockito 就像一位技艺精湛的木偶大师,能让各种依赖对象按你的剧本行动。它彻底解决了单元测试中 "依赖难搞" 的痛点 —— 不用再启动整个数据库,不用等待第三方服务响应,不用为测试准备复杂的前置条件。
有了这个模拟大师,你可以专注于测试目标代码的逻辑,轻松覆盖各种正常和异常场景,让单元测试的覆盖率和可靠性大幅提升。无论是测试复杂的服务层逻辑,还是验证边缘情况的处理,Mockito 都能让你的测试代码写得更简洁、跑得更高效,成为 Java 单元测试中不可或缺的得力工具。