如何在 Mockito 中正确处理依赖注入前的 Mock 方法存根

落伟同学_1335

落伟同学_1335

2026-09-05

261人浏览

原创

如何在 Mockito 中正确处理依赖注入前的 Mock 方法存根

当被测类构造函数依赖于 Mock 对象的方法返回值时,@InjectMocks 会先完成注入再执行 @BeforeEach,导致存根未生效而初始化失败;此时应放弃自动注入,改用手动构造实例并显式传入已存根的 Mock 对象。

当被测类构造函数依赖于 mock 对象的方法返回值时,`@injectmocks` 会先完成注入再执行 `@beforeeach`,导致存根未生效而初始化失败;此时应放弃自动注入,改用手动构造实例并显式传入已存根的 mock 对象。

在使用 Mockito 进行单元测试时,@Mock 和 @InjectMocks 是常用组合,但它们存在一个关键的执行顺序限制:@InjectMocks 的字段注入发生在测试方法执行前(即早于 @BeforeEach)。这意味着,若被测类(如 A)在构造函数中立即调用被注入依赖(如 B)的方法(例如 b.getC()),而该方法尚未被 when(...).thenReturn(...) 存根,则默认返回 null,进而触发 requireNonNull 抛出 NullPointerException,导致测试甚至无法启动。

上述问题的根本原因在于 @InjectMocks 并非“延迟注入”,而是由 MockitoExtension 在测试生命周期早期(beforeEach 之前)完成字段赋值和构造器调用。因此,在 @BeforeEach 中对 @Mock B b 进行的 stubbing 已然“为时已晚”。

✅ 正确解法:绕过 @InjectMocks,手动控制对象创建时机

@ExtendWith(MockitoExtension.class)
class ATest {
    @Mock
    B b;

    A a; // 不加 @InjectMocks

    @BeforeEach
    void setUp() {
        when(b.getC()).thenReturn("mocked-value"); // ✅ 存根先于构造执行
        a = new A(b); // ✅ 手动构造,确保依赖已就绪
    }

    @Test
    void test() {
        assertNotNull(a.c);
        assertEquals("mocked-value", a.c);
    }
}

? 优势说明:

  • 时序可控:stubbing 与构造严格按需顺序执行;
  • 语义清晰:测试意图一目了然——“我用这个 Mock 创建 A”;
  • 调试友好:避免 @InjectMocks 的黑盒行为(如字段注入 vs 构造器注入的歧义);
  • 兼容性强:适用于 final 字段、不可变对象、复杂初始化逻辑等场景。

⚠️ 注意事项:

  • 若类有多个构造器,请确保调用的是目标构造器(通常含依赖参数的那个);
  • 避免在 setUp() 外部(如字段初始化块)创建被测实例,否则仍可能触发早于 stubbing 的构造;
  • 如需复用相同初始化逻辑,可封装为私有工厂方法,但勿在 @Mock 字段声明处直接 new A(b)(此时 b 尚未初始化)。

总之,@InjectMocks 是便利工具,而非必需范式。当构造逻辑与 Mock 行为强耦合时,回归显式、确定性的手动构造,反而是更稳健、更可维护的测试实践。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
软件测试常用工具
软件测试常用工具

软件测试常用工具有Selenium、JUnit、Appium、JMeter、LoadRunner、Postman、TestNG、LoadUI、SoapUI、Cucumber和Robot Framework等等。测试人员可以根据具体的测试需求和技术栈选择适合的工具,提高测试效率和准确性 。

2023.10.13

4350

8

java测试工具有哪些
java测试工具有哪些

java测试工具有JUnit、TestNG、Mockito、Selenium、Apache JMeter和Cucumber。php还给大家带来了java有关的教程,欢迎大家前来学习阅读,希望对大家能有所帮助。

2023.10.23

2741

10

Java 单元测试
Java 单元测试

本专题聚焦 Java 在软件测试与持续集成流程中的实战应用,系统讲解 JUnit 单元测试框架、Mock 数据、集成测试、代码覆盖率分析、Maven 测试配置、CI/CD 流水线搭建(Jenkins、GitHub Actions)等关键内容。通过实战案例(如企业级项目自动化测试、持续交付流程搭建),帮助学习者掌握 Java 项目质量保障与自动化交付的完整体系。

2025.10.24

1026

26

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

2026.09.30

120

10

LLVM RISC-V参数配置教程
LLVM RISC-V参数配置教程

本专题介绍LLVM对RISC-V基础ISA和扩展的支持方式,涵盖RV32、RV64、标准扩展、实验性扩展、厂商扩展、-menable-experimental-extensions和版本差异。

2026.09.30

100

14

LLVM IR中间表示入门指南
LLVM IR中间表示入门指南

本专题整理LLVM IR的核心概念,包括中间表示作用、模块结构、函数、基本块、SSA形式、类型系统和常见语法,帮助新手理解LLVM编译流程中的关键层。

2026.09.30

80

12

PDF转图片方法
PDF转图片方法

需要把 PDF 页面用于上传、预览、分享或图片归档时,PDF 转图片方法专题整理 JPG/PNG 格式选择、逐页导出、清晰度设置、批量下载和结果检查等流程,帮助用户稳定完成 PDF 图片化处理。

2026.09.30

60

26

PixTV AI视频生成与无限画布创作
PixTV AI视频生成与无限画布创作

PixTV专题整理AI视频与视觉内容创作相关功能使用教程,涵盖AI生图、视频生成、无限画布、多模型创作、素材管理、声音音乐及视频剪辑等功能,帮助用户快速掌握PixTV从创意到成片的完整制作方法。

2026.09.29

80

15

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

2026.09.23

280

15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.4万人学习