如何在单元测试中正确注入 @InjectMocks 创建的模拟对象

陌明君_9034

陌明君_9034

2026-08-15

297人浏览

原创

如何在单元测试中正确注入 @InjectMocks 创建的模拟对象

本文详解在 Mockito 测试中如何将 @InjectMocks 创建的被测对象(如 Player)自动注入到其依赖对象(如 Game)中,并对比 Spring、Spring Boot 及纯 Java 场景下的不同实现方式。

本文详解在 mockito 测试中如何将 `@injectmocks` 创建的被测对象(如 `player`)自动注入到其依赖对象(如 `game`)中,并对比 spring、spring boot 及纯 java 场景下的不同实现方式。

在单元测试中,@InjectMocks 并非用于“提供可被注入的实例”,而是用于创建被测类的实例,并自动将标注了 @Mock@Spy 的字段注入其构造函数或 setter 中。因此,若你希望 Game 类使用一个已由 @InjectMocks 构建的 Player 实例,需明确:@InjectMocks 不会将自身“暴露为可注入的 Bean”——它只负责单次构建与注入,不参与后续依赖链传递

✅ 正确做法:按测试目标选择注入策略

1. 使用 @Mock + @InjectMocks 进行纯 Mockito 单元测试(推荐)

Player 是被测对象的依赖项(而非被测对象本身),应将其声明为 @Mock,再让 @InjectMocks Game 自动完成注入:

@ExtendWith(MockitoExtension.class)
class GameTest {

  @Mock
  private Player player; // 模拟依赖,非被测对象

  @InjectMocks
  private Game game; // 被测对象,自动注入 player

  @Test
  void shouldReturnPlayerName() {
    // 给 mock 行为打桩
    when(player.getName()).thenReturn("Alice");

    String result = game.getPlayerName();

    assertEquals("Alice", result);
    verify(player).getName();
  }
}

⚠️ 注意:此时 Player 是模拟对象(@Mock),不是通过 @InjectMocks Player player 创建的真实/半真实实例。若你确实需要 Player 是部分真实对象(如仅模拟其 Tool 依赖),请改用 @Spy 配合 @Mock Tool

2. 使用 Spring 容器管理真实对象(集成测试场景)

若需 PlayerGame 均为真实实例(例如验证完整构造链),应交由 Spring 容器管理依赖:

@SpringBootTest // 或 @ContextConfiguration(非 Boot 项目)
class GameIntegrationTest {

  @Autowired
  private Game game; // Spring 自动装配完整对象图:Game ← Player ← Tool

  @Test
  void shouldLoadGameWithRealPlayer() {
    assertNotNull(game);
    assertNotNull(game.getPlayer()); // Player 已由 Spring 实例化并注入
  }
}

此时无需手动 new Game(player),Spring 会解析 @Inject 构造器并递归注入 Tool → Player → Game

3. 手动组装(无框架轻量测试)

在不引入任何 DI 框架时,必须显式构造依赖链:

class GameManualTest {

  private Game game;

  @BeforeEach
  void setUp() {
    Tool tool = new Tool();
    Player player = new Player(tool); // 真实 Player 实例
    game = new Game(player);           // 手动注入
  }

  @Test
  void shouldWorkWithRealObjects() {
    assertEquals("expected", game.play());
  }
}

❌ 常见误区澄清

  • @InjectMocks Player player; 仅创建并注入 Player 实例到当前测试类字段,不会使其成为 Game 构造器的自动候选;
  • @InjectMocks Game game; 不会自动识别并复用同名的 player 字段——它只扫描 @Mock/@Spy 字段匹配类型,而 @InjectMocks Player player 是一个 被注入对象,不是 可注入的 mock
  • MockitoAnnotations.initMocks(this)(旧版 API)已被 @ExtendWith(MockitoExtension.class) 取代,务必使用扩展模型以确保生命周期正确。

✅ 总结:三步决策法

  1. 目标是隔离测试 Game 行为?@Mock Player + @InjectMocks Game(最常用)
  2. 目标是验证整个 DI 链路(含 Tool→Player→Game)? → 用 @SpringBootTest@ContextConfiguration
  3. 无框架且需最小依赖?@BeforeEach 中手动 new 并组装

选择合适策略,才能让测试既精准又可维护。

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

3890

8

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

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

2023.10.23

2341

10

Java 单元测试
Java 单元测试

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

2025.10.24

906

26

AI视频生成软件推荐
AI视频生成软件推荐

本专题汇总了当前主流的AI视频生成软件推荐与排行榜单,涵盖seko、AniShort、剧云、Lovart、LiblibAI及立刻mv等热门工具。同时整理了各软件在文生视频、图生视频、时长限制、画质表现及免费额度等方面的差异对比,助您快速选对适合创作需求的AI视频生成工具。

2026.09.16

140

9

ai生成视频的工具免费版合集
ai生成视频的工具免费版合集

本专题汇总了当前免费AI生成视频工具的排行榜与推荐清单,涵盖seko、讯飞智作、AniShort及剧云、Lovart等多模型集成平台。同时整理了各工具的免费额度、输出时长、水印政策及适用场景差异,助您快速选择合适工具开启AI视频创作。

2026.09.16

60

10

Pandas时间序列分析与可视化报表
Pandas时间序列分析与可视化报表

本专题整理Pandas日期转换、时间索引、重采样、滚动窗口、时区处理、plot绘图、Styler表格样式和报表输出方法。

2026.09.16

60

23

Pandas数据筛选索引与清洗处理
Pandas数据筛选索引与清洗处理

本专题整理Pandas中的loc、iloc、条件筛选、query查询、缺失值处理、重复值删除、类型转换和字符串列清洗方法。

2026.09.16

40

25

Pandas数据读取导入与文件导出处理
Pandas数据读取导入与文件导出处理

本专题整理Pandas读取CSV、Excel、JSON、SQL、Parquet等文件的方法,以及to_csv、to_excel、to_sql和to_parquet等常用数据导出流程。

2026.09.16

40

27

GDB怎么设置断点
GDB怎么设置断点

本专题介绍GDB按照函数名、源代码行号和文件位置设置断点的方法,详细说明run、continue、next、step等命令的配合使用,帮助定位程序崩溃、逻辑异常及代码未按预期执行的问题。

2026.09.11

360

28

热门下载

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

精品课程

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

共6课时 | 54.6万人学习

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

共89课时 | 133万人学习