1. 引言

软件测试是开发生命周期中的关键阶段,帮助我们评估、识别和提升软件质量。测试框架通过预定义工具简化这一过程。本文将探讨JUnit、Mockito的作用及二者的核心差异。

2. JUnit是什么?

JUnit是最广泛使用的单元测试框架之一,JUnit 5是其最新版本。该版本专注于Java 8+,支持多种测试风格。

JUnit 5通过断言、注解和测试运行器执行测试用例,主要面向单元测试,专注于隔离测试方法和类。

运行时要求Java 8+,但已编译的旧版本JDK代码仍可测试。典型JUnit测试类结构如下:

public class JunitVsMockitoUnitTest {
    @Test
    public void whenUsingJunit_thenObjectCanBeInstantiated() {
        InstantiableClassForJunit testableClass = new InstantiableClassForJunit();

        assertEquals("tested unit", testableClass.testableComponent());
    }
}

示例中创建了InstantiableClassForJunit类,其方法返回String。注意assertEquals()导入自Assertions类,这是JUnit 5(Jupiter)的典型特征。

3. Mockito是什么?

Mockito是由Szczepan Faber等人开发的Java框架,采用与传统"expect-run-verify"模拟库不同的交互验证方式。其核心优势包括:

✅ 轻量级API,快速启动模拟
✅ 支持模拟具体类和接口
✅ 简洁的注解语法(如@Mock
✅ 精准的错误定位
✅ 自定义参数匹配器

结合Mockito后的代码示例:

@ExtendWith(MockitoExtension.class)
public class JunitVsMockitoUnitTest {
    @Mock 
    NonInstantiableClassForMockito mock;

    // 前文的JUnit方法

    @Test
    public void whenUsingMockito_thenObjectNeedsToBeMocked() {
        when(mock.nonTestableComponent()).thenReturn("mocked value");

        assertEquals("mocked value", mock.nonTestableComponent());
    }
}

关键变化:

  1. 添加@ExtendWith(MockitoExtension.class)启用Mockito
  2. 使用@Mock创建模拟对象
  3. 通过when().thenReturn()定义模拟行为(需在断言前配置)

⚠️ 注意:此构造让Mockito在调用特定方法时返回预设值,而非实际执行逻辑。

4. JUnit与Mockito的核心差异

4.1 测试用例结构

JUnit通过注解构建测试结构:

  • @Test:标记测试方法
  • @ParametrizedTest:参数化测试
  • @BeforeEach/@AfterEach:单个测试前后执行
  • @BeforeAll/@AfterAll:所有测试前后执行

Mockito则专注于:

  • 创建模拟对象
  • 配置模拟行为(返回值)
  • 验证交互行为(调用次数、参数等)

4.2 测试范围

JUnit用于单元测试,隔离测试单个组件(方法/类)的逻辑。

Mockito是模拟框架,核心价值在于:

  • 生成模拟对象替代真实依赖
  • 控制模拟对象的行为
  • 验证交互过程

典型场景:模拟外部接口响应,避免真实调用或解决无法实例化的问题。

4.3 测试替身(Test Doubles)

JUnit侧重于:

  • 具体对象实现
  • 测试替身(如fakes/stubs),即有限行为的模拟依赖

Mockito使用:

  • 动态对象(基于反射的mocks)
  • 可定制化行为的模拟对象

4.4 测试覆盖率

JaCoCo等覆盖率工具与JUnit集成,而非Mockito。这再次印证二者的定位差异:

  • JUnit:测试执行框架
  • Mockito:测试辅助工具(需在JUnit等框架内使用)

4.5 对象模拟

Mockito的核心能力:

  • 精确指定模拟对象的行为预期
  • 快速构建测试场景

JUnit的定位:

  • 专注断言验证
  • 无内置模拟功能

5. 结论

JUnit和Mockito是Java生态的两大测试支柱:

  • JUnit:测试基础设施,提供结构化测试环境和执行引擎
  • Mockito:测试增强工具,通过模拟复杂依赖简化单元测试

二者协作模式:

  1. JUnit搭建测试骨架
  2. Mockito模拟外部依赖
  3. JUnit执行断言验证
  4. Mockito验证交互行为

代码示例见GitHub仓库


原始标题:The Difference Between JUnit and Mockito | Baeldung