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

Spring Integration中Mock JMS连接工厂的集成测试报错排查

解决Spring Boot 1.5.3下Mock JMS连接工厂的集成测试问题

咱们先梳理下你的场景:生产环境用WebSphere的JNDI查找JMS连接工厂,测试环境切换到Tomcat,想用ActiveMQ的VM Broker来Mock JMS连接,结果遇到了两个棘手的错误,咱们一步步来解决。

第一个错误:MockMvc无法自动注入

No qualifying bean of type 'org.springframework.test.web.servlet.MockMvc' available: expected at least 1 bean which qualifies as autowire candidate.

这个问题很明确:@SpringBootTest注解默认不会自动配置MockMvc实例,所以Spring找不到对应的bean来注入。解决方法有两种:

方案1:添加自动配置注解

直接在你的测试类上加上@AutoConfigureMockMvc注解,Spring Boot会自动帮你创建并配置好MockMvc实例,这样@Autowired MockMvc mvc就能正常工作了:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc // 加上这个注解
public class MQControllerTest {
    // ... 原有代码
}

方案2:手动构建MockMvc

如果你的测试不需要加载完整的Spring上下文,也可以在@Before方法里手动构建MockMvc:

@Before
public void setup() throws JMSException{
    Mockito.reset(this.mockJmsTemplate);
    // 手动构建MockMvc
    mvc = MockMvcBuilders.standaloneSetup(mqController).build();
}

不过考虑到你需要用到JmsTemplate和SourcePollingChannelAdapter这些Spring管理的bean,推荐用第一种方案。

第二个错误:JNDI初始化异常

Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property...

这个错误说明你的Spring容器在初始化时,仍然在尝试创建JNDI相关的bean,大概率是因为测试环境没有完全覆盖生产环境的JNDI配置,或者你的util:constant配置存在时机问题。咱们来逐一解决:

1. 用Spring Profile隔离生产/测试配置

首先,把生产环境的JNDI配置标记为prod profile,确保测试时不会加载:

<!-- 生产环境配置文件,比如application-prod.xml -->
<beans profile="prod">
    <jee:jndi-lookup id="narconFactory" jndi-name="LBARQCF" resource-ref="false"/>
    <jee:jndi-lookup id="vanconFactory" jndi-name="..."/> <!-- 你的另一个JNDI配置 -->
</beans>

然后在测试类上激活test profile:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("test") // 激活测试profile
public class MQControllerTest {
    // ... 原有代码
}

2. 替换util:constant,用@Bean定义测试连接工厂

你原来用util:constant引用测试类的静态字段,这里存在一个时机问题:Spring容器初始化时,测试类的静态字段可能还没被初始化,导致bean创建失败,进而触发了原来的JNDI配置加载。

咱们直接在测试类里用@Bean来定义测试用的连接工厂,让Spring来管理bean的创建时机:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("test")
public class MQControllerTest {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private MQController mqController;

    // 定义基础的ActiveMQ连接工厂
    @Bean
    public ConnectionFactory amqFactory() {
        return new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
    }

    // 定义narconFactory,替代原来的JNDI lookup
    @Bean
    public CachingConnectionFactory narconFactory(ConnectionFactory amqFactory) {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(amqFactory);
        connectionFactory.setCacheConsumers(false);
        return connectionFactory;
    }

    // 定义vanconFactory
    @Bean
    public CachingConnectionFactory vanconFactory(ConnectionFactory amqFactory) {
        return new CachingConnectionFactory(amqFactory);
    }

    @Autowired
    private CachingConnectionFactory narconFactory;

    @Autowired
    private JmsTemplate mockJmsTemplate;

    @Autowired
    private SourcePollingChannelAdapter startJms;

    @Before
    public void setup() throws JMSException {
        Mockito.reset(mqController);
        // 初始化连接,替代原来的@BeforeClass逻辑
        narconFactory.createConnection().close();
    }

    @After
    public void tearDown() {
        // 重置连接,替代原来的@AfterClass逻辑
        narconFactory.resetConnection();
    }

    @Test
    public void test_tbm_vrijeDagenCorrectie() throws Exception {
        String expectedResponse ="";
        given(mqController.tmVDCorrect(any(String.class))).willReturn(expectedResponse);
        
        this.startJms.start();
        mvc.perform(get("/tm/vdc/{dgn}","2016-01-16"))
                .andExpect(status().isOk());
    }
}

这样一来,测试环境下Spring会优先使用测试类中定义的narconFactory和vanconFactory,完全跳过生产环境的JNDI配置,也就不会再触发NoInitialContextException了。

3. 调整连接初始化逻辑

把原来的@BeforeClass和@AfterClass改成@Before和@After,确保Spring容器已经初始化完成后再操作连接工厂,避免出现初始化时机的问题。

最后验证

做完以上调整后,重新运行测试:

  1. MockMvc应该能正常注入,不会再报找不到bean的错误;
  2. JNDI相关的异常会消失,因为测试环境已经完全使用ActiveMQ的VM Broker作为Mock连接工厂;
  3. 你的JMS相关逻辑会通过Mock的连接工厂运行,完成集成测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:37:31