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

Spring测试中@MockBean在目标Bean构造函数内Stub不生效该如何解决

问题根因

Spring上下文初始化阶段会完成所有Bean的实例化和依赖注入,MyBeanToTest的构造函数会在测试方法执行之前就被调用,你写在testSomething()里的Stub规则此时还没有执行,所以jmsTemplate.getConnectionFactory()默认返回null,触发空指针。

解决方案

有三种常用的调整方式可以解决这个问题:

方案1:提前在@BeforeAll阶段配置Stub(需配合静态Mock)

将JmsTemplate的Mock也改为静态,在所有Bean实例化前完成Stub配置:

@SpringBootTest
public class MyTestClass {
    @Autowired
    MyBeanToTest myBeanToTest;

    // 改为静态MockBean,上下文初始化时就会用这个静态实例
    @MockBean
    private static JmsTemplate jmsTemplate;
    
    @Mock
    private static ConnectionFactory connectionFactory;

    // 在Spring上下文初始化前执行Stub配置
    @BeforeAll
    static void initStub() throws JMSException {
        when(jmsTemplate.getConnectionFactory()).thenReturn(connectionFactory);
        // 连带Stub后续的createSession调用,避免二次空指针
        when(connectionFactory.createSession()).thenReturn(yourExpectedSessionMock);
    }

    @Test
    public void testSomething()  {
        // 直接写测试逻辑即可
        ...
    }
}

方案2:用@TestConfiguration提前配置带Stub规则的Mock

自定义测试配置类,在Bean实例化前就创建好带Stub的Mock对象:

@SpringBootTest
public class MyTestClass {
    @TestConfiguration
    static class TestMockConfig {
        @Bean
        public JmsTemplate jmsTemplate() throws JMSException {
            JmsTemplate mockJmsTemplate = Mockito.mock(JmsTemplate.class);
            ConnectionFactory mockCf = Mockito.mock(ConnectionFactory.class);
            when(mockJmsTemplate.getConnectionFactory()).thenReturn(mockCf);
            when(mockCf.createSession()).thenReturn(Mockito.mock(Session.class));
            return mockJmsTemplate;
        }
    }

    @Autowired
    MyBeanToTest myBeanToTest;

    @Test
    public void testSomething()  {
        ...
    }
}

方案3(设计层面优化,更推荐):避免在构造函数中执行依赖的调用逻辑

将构造函数中的初始化逻辑迁移到@PostConstruct方法,或者懒加载ConnectionFactory,这样可以更灵活的控制Stub时机,也符合Spring Bean的生命周期规范:

@Autowired
public MyBeanToTest(JmsTemplate jmsTemplate) {
    this.jmsTemplate = jmsTemplate;
}

@PostConstruct
public void init() throws JMSException {
    this.cf = this.jmsTemplate.getConnectionFactory();
    cf.createSession();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:27:03