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

如何用Mockito对同时含构造注入与字段注入的类进行Mock测试

问题解答

Mockito 原生支持混合依赖注入场景,无需修改业务代码字段权限、无需手动反射操作,正确使用 @InjectMocks 即可完成所有依赖注入。

@InjectMocks 注解的实例会按照以下顺序完成依赖注入:

  • 优先调用参数最多的构造方法,匹配测试类中声明的@Mock实例完成构造注入
  • 构造完成后,匹配剩余未注入的字段,自动通过反射完成私有字段注入,无需提供setter方法

SpecialClient的requestScope属性不会影响单元测试逻辑,单元测试无需启动Spring上下文,直接注入Mock实例即可。


正确测试代码示例(JUnit 5)

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

// 必须添加此注解启用Mockito注解驱动,否则所有Mockito注解不会生效
@ExtendWith(MockitoExtension.class)
class MyServiceTest {
    @Mock
    ClientOne clientOne;
    @Mock
    ClientTwo clientTwo;
    @Mock
    SpecialClient specialClient;

    // 直接标注@InjectMocks即可,无需手动new实例
    // Mockito会自动调用构造方法注入前两个依赖,再反射注入私有字段specialClient
    @InjectMocks
    MyService myService;

    @Test
    void testBizLogic() {
        // 此处直接调用myService的方法测试即可,三个依赖均为已初始化的mock实例,不会为null
    }
}

JUnit 4 适配写法

如果使用JUnit4,替换注解驱动即可:

import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class MyServiceTest {
    // 其余@Mock、@InjectMocks的声明和JUnit5完全一致
}

常见失效场景排查

如果使用@InjectMocks后specialClient仍为null,可检查以下问题:

  • 未启用Mockito注解驱动,未添加@ExtendWith(MockitoExtension.class)/@RunWith(MockitoJUnitRunner.class),也未在setup方法中调用MockitoAnnotations.openMocks(this)
  • 手动调用构造方法new了MyService实例,覆盖了@InjectMocks自动生成的已完成注入的实例
  • SpecialClient存在多个同类型的@Mock实例,未通过@Qualifier/@Named指定匹配名称

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:51:01