Mock 框架选型:Mockito、EasyMock、PowerMock 横向对比

一、为什么需要 Mock 框架?

在单元测试中,Mock 框架用于创建虚拟对象替代实际依赖组件,确保测试聚焦于被测单元本身,隔离外部影响。对于 Spring Boot 项目来说,Mock 通常用于替代 Service、Repository、HTTP 客户端等组件,提升测试速度和稳定性。

二、主流 Java Mock 框架介绍

框架 特点 适用场景
Mockito 使用最广泛,语法简洁,集成简单,支持行为验证和交互验证 大多数业务逻辑的单元测试
EasyMock 基于接口生成 Mock,使用录制-回放机制,语法风格不同于 Mockito 传统项目或接口驱动系统
PowerMock 可 Mock 静态方法、final 类、构造函数等 旧代码改造、遗留系统测试、难以解耦的代码单元

三、核心原理与架构理解

Mockito 原理简述

Mockito 基于 Java 动态代理(JDK Proxy / CGLIB)实现,通过运行时动态生成代理对象来拦截方法调用。

  • @Mock:创建模拟对象
  • @InjectMocks:自动注入依赖
  • Mockito.when().thenReturn():定义行为
  • Mockito.verify():验证方法调用

EasyMock 原理简述

EasyMock 使用“录制-回放”机制,测试先设置行为预期,然后执行方法,最后进行验证。

  • expect(service.getName()).andReturn("mock").once()
  • replay(service)
  • verify(service)

PowerMock 原理简述

PowerMock 基于 ASM 字节码操作实现,可以绕过 JVM 限制 mock:

  • 静态方法(static)
  • final 类、final 方法
  • 构造函数
  • private 方法

但这带来了字节码污染问题,不推荐与 JUnit5 一起使用(需使用 PowerMockRunner 或 MockitoJUnitRunner)


四、实践 DEMO:一个真实业务场景对比

场景背景:测试订单创建服务

public class OrderService {
   
    
    
    private PaymentService paymentService;
    
    public boolean createOrder(Order order) {
   
    
    
        boolean paid = paymentService.pay(order.getId(