SpringBootTest - 如何在集成测试中修改 DefaultMessageListenerContainer

问题描述

使用 Spring Boot v2.3.4.RELEASE、Spring v5.2.9.RELEASE、junit5、IBM MQ 运行

我正在编写一个集成 @SpringBoottest 来测试 MessageListener。

该测试会创建随机命名的队列,以保持构建管道的不同。 目前,@BeforeAll 测试创建这些队列并尝试修改 DefaultMessageListenerContainer Bean 中的目标名称。看来您无法在所有测试之前执行此操作,因为 spring 容器已经创建了 MessageListnerContainer 并忽略了容器中的更改。


@EnableJms

@Configuration

public class JmsConfig {

 

    @Autowired

    private Environment env;

   

    @Value("${inbound-queue}")

    private String inboundQueue;

 

    @Bean

    public MQConnectionFactory mqConnectionFactory() throws JMSException {

        MQConnectionFactory connectionFactory = new MQConnectionFactory();

        connectionFactory.setHostName(env.getProperty("mq.hostname")); //mq host name

        connectionFactory.setPort( Integer.parseInt(env.getProperty("mq.port"))); // mq port

        connectionFactory.setQueueManager(env.getProperty("mq.manager")); //mq queue manager

        connectionFactory.setChannel(env.getProperty("mq.channel")); //mq channel name

        connectionFactory.setTransportType(1); //WMQConstants.WMQ_CM_CLIENT

        return connectionFactory;

    }

 

    @Bean

    public DefaultMessageListenerContainer mqMessageEventContainer() throws JMSException {

        DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();

        container.setAutoStartup(true);

        container.setConnectionFactory(mqConnectionFactory());

        container.setDestinationName(inboundQueue);

        container.setMessageListener(new NotificationListener());

        return container;

    }

听众:


@Slf4j

public class NotificationListener implements MessageListener {

 

    @Override

    @Transactional()

    public void onMessage(Message msg) {

        log.debug("Received a {}",msg.getClass().getSimpleName());

        try {

            if (msg instanceof JMSObjectMessage) {

                JMSObjectMessage bmrMsg = (JMSObjectMessage) msg;

                log.debug("bmrMsg is a " + bmrMsg.getobject().getClass().getSimpleName());

测试:


    @Autowired

    private JmsConfig jmsConfig;

    @BeforeAll

    public void beforeAllTests(TestInfo testInfo) {

        log.info(START_TEST + testInfo.getTestMethod());

        buildTempQueues();

        log.info(END_TEST + testInfo.getTestMethod());

    }

 

    private void buildTempQueues() {

        assertthat(qHost).isNotNull();

        assertthat(qPortString).isNotNull();

        assertthat(qMgr).isNotNull();

        assertthat(qChannel).isNotNull();

        buildTempQueues(qHost,qPortString,qMgr,qChannel);

 

        Optional<String> qOpt = getQueueName(INBOUND_QUEUE_ENDING);

        if (qOpt.isPresent()) {

            String ibQueue = qOpt.get();

            ReflectionTestUtils.setField(jmsConfig,"inboundQueue",ibQueue);

            try {

                jmsConfig.mqMessageEventContainer().setDestinationName(ibQueue);

            } catch (JMSException e) {

                fail(e.getMessage());

            }

        } else {

            fail("Could NOT CONfigURE QUEUES FOR TESTING");

        }

 

        qOpt = getQueueName(FAILURE_QUEUE_ENDING);

        if (qOpt.isPresent()) {

            ReflectionTestUtils.setField(jmsService,"failureQueue",qOpt.get());

        }

    }

 

jmsConfig.mqMessageEventContainer().setDestinationName(ibQueue);

 

 

所以 jmsConfig.mqMessageEventContainer().setDestinationName(ibQueue);似乎没有更改 Bean,因为 Spring 上下文已经创建了侦听器....


        final CountDownLatch latch = new CountDownLatch(1);

        Executor executor = Executors.newSingleThreadExecutor();

        executor.execute(() -> {

            try {

 

                //then

                jmstemplate.convertAndSend(getQueueName(INBOUND_QUEUE_ENDING).get(),givenScript.getSubject());

                PCFMessage[] responses = getQueueDepth(qHost,qChannel,INBOUND_QUEUE_ENDING);

                assertthat(responses).isNotNull();

                for (PCFMessage response : responses) {

                    assertthat(0).isEqualTo(response.getCompCode());

                    assertthat(getQueueName(INBOUND_QUEUE_ENDING).get()).isEqualTo(trim(response.getStringParameterValue(MQConstants.MQCA_Q_NAME)));

                    assertthat(1).isEqualTo(response.getIntParameterValue(MQConstants.MQIA_CURRENT_Q_DEPTH));

                }

 

                while (notificationService.getMsgCt() == 0) {

                    Thread.sleep(2000);

                    log.debug("Messages processed = " + notificationService.getMsgCt());

                }

 

                // Now signal that our background task completed

                latch.countDown();

 

            } catch (JmsException | PCFException | InterruptedException e) {

                fail(e.getMessage());

            }

        });

 

        log.info("(T) waiting on latch...");

        try {

            // Block the test thread for at most 5 seconds before giving up and failing the test.

            boolean receivedSignal = latch.await(15,TimeUnit.SECONDS);

            log.info(String.format("(T) Test thread did wait on latch (timeout=%b)",!receivedSignal));

            assertthat(receivedSignal).isTrue();

 

            //Todo Test outboud queue has depth 1

        } catch (InterruptedException e) {

            fail(e.getMessage());

        }

日志:


12:42:49.876 [main] INFO  g.d.t.v.v.v.s.i.NotificationListenerTests.whenOnMessage_givenMessageOnQueue_thenProcessMessage -  (T) waiting on latch...

 

12:42:52.102 [pool-3-thread-1] DEBUG g.d.t.v.v.v.s.i.NotificationListenerTests.lambda$whenOnMessage_givenMessageOnQueue_thenProcessMessage$0 -  Messages processed = 0

 

12:42:54.102 [pool-3-thread-1] DEBUG g.d.t.v.v.v.s.i.NotificationListenerTests.lambda$whenOnMessage_givenMessageOnQueue_thenProcessMessage$0 -  Messages processed = 0

 

12:42:56.103 [pool-3-thread-1] DEBUG g.d.t.v.v.v.s.i.NotificationListenerTests.lambda$whenOnMessage_givenMessageOnQueue_thenProcessMessage$0 -  Messages processed = 0

 

12:42:58.103 [pool-3-thread-1] DEBUG g.d.t.v.v.v.s.i.NotificationListenerTests.lambda$whenOnMessage_givenMessageOnQueue_thenProcessMessage$0 -  Messages processed = 0

 

12:43:00.103 [pool-3-thread-1] DEBUG g.d.t.v.v.v.s.i.NotificationListenerTests.lambda$whenOnMessage_givenMessageOnQueue_thenProcessMessage$0 -  Messages processed = 0

 

12:43:02.104 [pool-3-thread-1] DEBUG g.d.t.v.v.v.s.i.NotificationListenerTests.lambda$whenOnMessage_givenMessageOnQueue_thenProcessMessage$0 -  Messages processed = 0

 

12:43:04.105 [pool-3-thread-1] DEBUG g.d.t.v.v.v.s.i.NotificationListenerTests.lambda$whenOnMessage_givenMessageOnQueue_thenProcessMessage$0 -  Messages processed = 0

 

12:43:04.879 [main] INFO  g.d.t.v.v.v.s.i.NotificationListenerTests.whenOnMessage_givenMessageOnQueue_thenProcessMessage -  (T) Test thread did wait on latch (timeout=true)

 

ERROR] Tests run: 1,Failures: 1,Errors: 0,Skipped: 0,Time elapsed: 33.779 s <<< FAILURE! - in gov.dhs.tsa.vcs.vet.vcsn.service.impl.NotificationListenerTests

[ERROR] whenOnMessage_givenMessageOnQueue_thenProcessMessage{TestInfo}  Time elapsed: 15.723 s  <<< FAILURE!

org.opentest4j.AssertionFailedError:

 

Expecting:

<false>

to be equal to:

<true>

but was not.

 

解决方法

  • 集合autoStartupfalse听者容器上。

  • 汽车电线的容器插入所述测试案例,并设置其目的地;然后start()的容器。

  • 您不需要的反射的东西 - 这是为时已晚。