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

SpringBootTest中如何在Autowired前完成Bean的Mock配置?

问题原因

你遇到的核心问题是Spring容器初始化Bean的时机早于Mock行为的设置时机:

  • 使用@MockBean时,Spring会先创建Mock实例并加入容器,随后初始化ClassC和ClassA(调用它们的构造方法),而你的@BeforeAll方法是在所有Bean初始化完成后才执行的,此时构造方法已经调用过b.get(),自然返回Mock的默认值null。
  • 用MockitoExtension+@InjectMocks时,Mockito会先初始化@Mock,再自动实例化@InjectMocks标注的Bean(调用构造方法),最后才执行@BeforeAll,同样导致构造时Mock未配置行为。
解决思路

方案1:基于Spring容器,提前配置Mock行为

直接通过@Bean方法创建并配置好Mock的ClassB,让Spring容器在初始化ClassC和ClassA之前就拿到已经设置好返回值的Mock实例:

@ExtendWith(SpringExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@EnableConfigurationProperties
@SpringBootTest(classes = {ClassA.class, ClassC.class})
public class SomeTest {

    @Bean
    public ClassB b() {
        ClassB mockB = Mockito.mock(ClassB.class);
        Mockito.when(mockB.get()).thenReturn("koo");
        return mockB;
    }
    
    @Autowired
    private ClassC c;

    @Autowired
    private ClassA a;

    @Test
    void test() {
       // 执行测试逻辑
    }
}

方案2:纯Mockito单元测试,手动控制实例化顺序

如果不需要启动Spring容器,完全用Mockito做单元测试,需要先配置Mock的行为,再手动实例化ClassC和ClassA,确保构造方法调用时Mock已经准备好:

@ExtendWith(MockitoExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class SomeTest {

    @Mock
    private ClassB b;

    private ClassC c;
    private ClassA a;

    @BeforeAll
    void setup() {
        // 先配置Mock行为
        Mockito.when(b.get()).thenReturn("koo");
        // 再手动实例化依赖Mock的Bean
        c = new ClassC(b);
        a = new ClassA(b, c);
    }

    @Test
    void test() {
       // 执行测试逻辑
    }
}

这两种方案都能保证ClassC和ClassA构造时,b.get()返回的是你预期的"koo",从而得到想要的打印结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 12:43:21