You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Mockito 4.5 Mock构造函数内创建的Child字段并注入Parent

解决Mockito 4.5中Mock构造函数内new出的Child对象问题

直接用Mockito 4.5提供的MockedConstruction就能解决这个问题——它可以拦截Child类的构造调用,自动把构造出来的实例替换成mock对象,不需要手动注入到Parent里。具体实现步骤如下:

1. 依赖准备(以JUnit5为例)

确保测试依赖包含Mockito的JUnit5扩展:

<!-- Maven依赖示例 -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>4.5.1</version>
    <scope>test</scope>
</dependency>

2. 编写测试代码

在测试方法中,用MockedConstruction包裹Parent的实例化逻辑,同时指定Child的mock行为:

import org.junit.jupiter.api.Test;
import org.mockito.MockedConstruction;
import static org.mockito.Mockito.*;

public class ParentTest {

    @Test
    void testThanksGivingVisit() {
        // 1. 准备测试依赖的mock对象
        Legacy mockLegacy = mock(Legacy.class);
        Config mockConfig = mock(Config.class);
        // 模拟config.getBirthCertificate()的返回值(按需配置)
        when(mockConfig.getBirthCertificate()).thenReturn("fake-cert-id");

        // 2. 用MockedConstruction拦截Child构造,生成mock实例并配置行为
        try (MockedConstruction<Child> mockedChild = mockConstruction(Child.class,
                (mock, context) -> {
                    // 指定withDrawFromBackAccount的返回值,避免触发DB操作
                    when(mock.withDrawFromBackAccount()).thenReturn(200);
                })) {

            // 3. 实例化Parent——此时构造函数里new的Child是mock对象
            Parent parent = new Parent(mockLegacy, mockConfig);

            // 4. 调用待测试方法
            Result result = parent.thanksGivingVisit();

            // 5. 编写业务断言(根据你的Result逻辑调整)
            // 示例:assertEquals(预期值, result.getAmount());

            // 可选:验证Child的方法是否被调用
            Child childMock = mockedChild.constructed().get(0);
            verify(childMock, times(1)).withDrawFromBackAccount();
        }
    }
}

关键原理说明

  • MockedConstruction会在它的作用域(try-with-resources块内)拦截所有Child类的构造调用,返回预先配置好的mock对象。
  • 当你在块内实例化Parent时,Parent构造函数里new Child(...)的调用会被Mockito自动拦截,生成的child字段就是mock实例,完全不需要额外的注入操作。
  • try-with-resources语法会自动关闭MockedConstruction,避免该mock行为影响其他测试用例。

注意事项

  • 如果不需要配置mock的行为,可以简化为mockConstruction(Child.class),此时mock方法会返回对应类型的默认值(比如int类型返回0)。
  • 务必确保MockedConstruction的作用域包裹住所有会创建Child实例的代码,否则拦截会失效。

内容的提问来源于stack exchange,提问作者Dreamer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 07:07:25