spring - SpringBootTest - 如何在集成测试中修改 DefaultMessageListenerContainer
问题描述
使用 Spring Boot v2.3.4.RELEASE、Spring v5.2.9.RELEASE、JUnit5、IBM MQ 运行
我正在编写一个测试 MessageListener 的集成 @SpringBootTest。
测试创建随机命名队列以保持构建管道的不同。目前@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, qPortString, qMgr, 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.
解决方案
在侦听器容器上设置
autoStartup
为。false
自动将容器连接到测试用例并设置其目的地;然后
start()
是容器。你不需要那些反射的东西——太晚了。
推荐阅读
- laravel - 在字符串上调用成员函数 notify()
- html - 沿菱形路径的 3D 立方体运动
- python - 差异 PyCharm - Google Colab
- excel - 如何在 VBA 中将新元素附加到 XMLDOM?
- python - Django Field 'id' 需要一个数字,但得到了 '
' - python - 如何使用时间模块计算 Python 中两个日期之间的天数差?
- flutter - Flutter Navigation 路线运行不顺畅
- javascript - 如何阻止孩子的拖动事件触发父母的拖动事件
- javascript - Jquery:我想明智地将数据添加到一个简单的 html 表列
- html - HTML如何将文本覆盖在另一个文本上并垂直居中