Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Junit测试中等待SpringJMS侦听器线程完成执行_Spring_Multithreading_Spring Boot_Spring Jms_Junit5 - Fatal编程技术网

如何在Junit测试中等待SpringJMS侦听器线程完成执行

如何在Junit测试中等待SpringJMS侦听器线程完成执行,spring,multithreading,spring-boot,spring-jms,junit5,Spring,Multithreading,Spring Boot,Spring Jms,Junit5,我有一个使用SpringJMS的SpringBoot应用程序。有没有办法告诉测试方法等待jms lister util完成执行,而不在将要测试的实际代码中使用锁存器 以下是JMS侦听器代码: import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotyp

我有一个使用SpringJMS的SpringBoot应用程序。有没有办法告诉测试方法等待jms lister util完成执行,而不在将要测试的实际代码中使用锁存器

以下是JMS侦听器代码:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

import javax.jms.Message;
import javax.jms.QueueSession;


@Component
public class MyListener {


    @Autowired
    MyProcessor myProcessor;


    @JmsListener(destination = "myQueue", concurrency = "1-4")
    private void onMessage(Message message, QueueSession session) {
        myProcessor.processMessage(message, session);
    }
}




注:在不向实现代码(MyListener和MyProcessor)中添加测试目的代码的情况下,是否适用于解决此问题

代理侦听器并添加建议以倒计时闩锁;这是我最近为卡夫卡通片做的一个

@Test
public void test() throws Exception {
    this.template.send("so50214261", "foo");
    assertThat(TestConfig.latch.await(10, TimeUnit.SECONDS)).isTrue();
    assertThat(TestConfig.received.get()).isEqualTo("foo");
}

@Configuration
public static class TestConfig {

    private static final AtomicReference<String> received = new AtomicReference<>();

    private static final CountDownLatch latch = new CountDownLatch(1);

    @Bean
    public static MethodInterceptor interceptor() {
        return invocation -> {
            received.set((String) invocation.getArguments()[0]);
            return invocation.proceed();
        };
    }

    @Bean
    public static BeanPostProcessor listenerAdvisor() {
        return new ListenerWrapper(interceptor());
    }

}

public static class ListenerWrapper implements BeanPostProcessor, Ordered {

    private final MethodInterceptor interceptor;

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }

    public ListenerWrapper(MethodInterceptor interceptor) {
        this.interceptor = interceptor;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof Listener) {
            ProxyFactory pf = new ProxyFactory(bean);
            NameMatchMethodPointcutAdvisor advisor = new NameMatchMethodPointcutAdvisor(this.interceptor);
            advisor.addMethodName("listen");
            pf.addAdvisor(advisor);
            return pf.getProxy();
        }
        return bean;
    }

}
@测试
public void test()引发异常{
此.template.send(“so50214261”,“foo”);
assertThat(TestConfig.latch.await(10,TimeUnit.SECONDS)).isTrue();
assertThat(TestConfig.received.get()).isEqualTo(“foo”);
}
@配置
公共静态类TestConfig{
接收到私有静态最终AtomicReference=新AtomicReference();
专用静态最终倒计时闩锁=新倒计时闩锁(1);
@豆子
公共静态方法拦截器拦截器(){
返回调用->{
received.set((字符串)invocation.getArguments()[0]);
返回调用。继续();
};
}
@豆子
公共静态BeanPostProcessor listenerAdvisor(){
返回新的ListenerWrapper(拦截器());
}
}
公共静态类ListenerWrapper实现BeanPostProcessor,已订购{
专用最终方法拦截器;
@凌驾
public int getOrder(){
返回顺序。最高优先级;
}
公共ListenerWrapper(MethodInterceptor interceptor){
this.interceptor=拦截器;
}
@凌驾
公共对象后处理初始化后(对象bean、字符串beanName)抛出BeansException{
if(侦听器的bean实例){
ProxyFactory pf=新的ProxyFactory(bean);
NameMatchMethodPointcutAdvisor advisor=新的NameMatchMethodPointcutAdvisor(this.interceptor);
advisor.addMethodName(“倾听”);
私人助理顾问(顾问);
返回pf.getProxy();
}
返回豆;
}
}

(但您应该在调用
继续()
)后将倒计时移到。

带有@JmsListener注释的方法会在消息完成后删除消息,因此一个好的选择是读取现有消息的队列,并假设在方法完成后队列为空。下面是一段代码,用于计算队列中的消息

private int countMessages() {
    return jmsTemplate.browse(queueName, new BrowserCallback<Integer>() {
      @Override
      public Integer doInJms(Session session, QueueBrowser browser) throws JMSException {
        return Collections.list(browser.getEnumeration()).size();
      }
    });
  }
你可能想看看
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.util.SocketUtils;

import javax.jms.ConnectionFactory;

@EnableJms
@Configuration
@Profile("test")
public class JmsTestConfig {

    public static final String BROKER_URL =
            "tcp://localhost:" + SocketUtils.findAvailableTcpPort();


    @Bean
    public BrokerService brokerService() throws Exception {
        BrokerService brokerService = new BrokerService();
        brokerService.setPersistent(false);
        brokerService.addConnector(BROKER_URL);

        return brokerService;
    }

    @Bean
    public ConnectionFactory connectionFactory() {
        return new ActiveMQConnectionFactory(BROKER_URL);
    }

    @Bean
    public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
        JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
        return jmsTemplate;
    }

}
@Test
public void test() throws Exception {
    this.template.send("so50214261", "foo");
    assertThat(TestConfig.latch.await(10, TimeUnit.SECONDS)).isTrue();
    assertThat(TestConfig.received.get()).isEqualTo("foo");
}

@Configuration
public static class TestConfig {

    private static final AtomicReference<String> received = new AtomicReference<>();

    private static final CountDownLatch latch = new CountDownLatch(1);

    @Bean
    public static MethodInterceptor interceptor() {
        return invocation -> {
            received.set((String) invocation.getArguments()[0]);
            return invocation.proceed();
        };
    }

    @Bean
    public static BeanPostProcessor listenerAdvisor() {
        return new ListenerWrapper(interceptor());
    }

}

public static class ListenerWrapper implements BeanPostProcessor, Ordered {

    private final MethodInterceptor interceptor;

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }

    public ListenerWrapper(MethodInterceptor interceptor) {
        this.interceptor = interceptor;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof Listener) {
            ProxyFactory pf = new ProxyFactory(bean);
            NameMatchMethodPointcutAdvisor advisor = new NameMatchMethodPointcutAdvisor(this.interceptor);
            advisor.addMethodName("listen");
            pf.addAdvisor(advisor);
            return pf.getProxy();
        }
        return bean;
    }

}
private int countMessages() {
    return jmsTemplate.browse(queueName, new BrowserCallback<Integer>() {
      @Override
      public Integer doInJms(Session session, QueueBrowser browser) throws JMSException {
        return Collections.list(browser.getEnumeration()).size();
      }
    });
  }
jmsTemplate.convertAndSend(queueName, "***MESSAGE CONTENT***");
while (countMessages() > 0) {
    log.info("number of pending messages: " + countMessages());
    Thread.sleep(1_000l);
}
// continue with your logic here