RabbitListenerConfigureIntegrationTests示例

时间:2019-03-15 17:37:47

标签: spring-amqp

我正在寻找RabbitListenerConfigurer和RabbitListenerEndpointRegistrar的一些集成测试示例,并调用@rabbitListner批注并测试消息转换并传递其他参数,例如Channel和message属性等。 像这样

@RunWith(SpringJUnit4ClassRunner.class)
public class RabbitListenerConfigureIntegrationTests {

    public final String sampleMessage="{\"ORCH_KEY\":{\"inputMap\":{},\"outputMap\":{\"activityId\":\"10001002\",\"activityStatus\":\"SUCCESS\"}}}";

    @Test
    public void testRabiitListenerConfigurer() throws Exception {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
                EnableRabbitConfigWithCustomConversion.class);
        RabbitListenerConfigurer registrar = ctx.getBean(RabbitListenerConfigurer.class);
        /* I want to get the Listener instance here */
        Message message = MessageBuilder.withBody(sampleMessage.getBytes())
                 .andProperties(MessagePropertiesBuilder.newInstance()
                .setContentType("application/json")
                .build())
                 .build();
        /* call listener.onmessage(message) and that intern pass the call back to @rabbit listener and by that time MessageHandler which is registered should kick off and convert the message */
    }

    @Configuration
    @EnableRabbit
    public static class EnableRabbitConfigWithCustomConversion implements RabbitListenerConfigurer {

        @Override
        public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
            registrar.setMessageHandlerMethodFactory(messageHandlerMethodFactory());

        }

        @Bean
        public ConnectionFactory mockConnectionFactory() {
            return mock(ConnectionFactory.class);
        }

        @Bean
        public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
            SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
            factory.setConnectionFactory(mockConnectionFactory());
            factory.setAutoStartup(false);
            return factory;
        }

        @Bean
        MessageHandlerMethodFactory messageHandlerMethodFactory() {
            DefaultMessageHandlerMethodFactory messageHandlerMethodFactory = new DefaultMessageHandlerMethodFactory();
            messageHandlerMethodFactory.setMessageConverter(consumerJackson2MessageConverter());
            return messageHandlerMethodFactory;
        }

        @Bean
        public MappingJackson2MessageConverter consumerJackson2MessageConverter() {
            return new MappingJackson2MessageConverter();
        }

        @Bean 
        public  Listener messageListener1() {
            return new Listener();
        }

    }

public class Listener {

    @RabbitListener(queues = "QUEUE")
    public void listen(ExchangeDTO dto, Channel chanel) {
        System.out.println("Result:" + dto.getClass() + ":" + dto.toString());
        /*ExchangeDTO dto = (ExchangeDTO)messageConverter.fromMessage(message);
        System.out.println("dto:"+dto);*/
    }
}

编辑2 我没有用值填充Exchange DTO。相反,我得到空值 这是Log: 15:00:50.994 [main]调试org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter-处理[GenericMessage [payload = byte [93],headers = {contentType = application / json,id = 8bf86bf1-7e45-d136 -9126-69959f92f100,时间戳= 1552680050993}]] 结果:类com.dsicover.dftp.scrubber.subscriber.ExchangeDTO:DTO [inputMap = {},outputMap = {}]

public class ExchangeDTO implements Serializable {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private HashMap<String, Object> inputMap = new HashMap<String, Object>();
        private HashMap<String, Object> outputMap = new HashMap<String, Object>();

        public HashMap<String, Object> getInputMap() {
            return inputMap;
        }

        public void setInputMap(HashMap<String, Object> inputMap) {
            this.inputMap = inputMap;
        }

        public HashMap<String, Object> getOutputMap() {
            return outputMap;
        }

        public void setOutputMap(HashMap<String, Object> outputMap) {
            this.outputMap = outputMap;
        }

        @Override
        public String toString() {
            return "DTO [inputMap=" + this.inputMap + ", outputMap=" + this.outputMap + "]";
        }
}

Jackson2MessageConverter中是否缺少任何内容。

2 个答案:

答案 0 :(得分:0)

根据您要求将所有东西都放在船上的复杂要求,我看不到我们如何与mock(ConnectionFactory.class)达成交易。我们需要进行更多模拟才能使所有功能正常工作。

相反,我建议对现有的RabbitMQ或至少嵌入式QPid进行 real 集成测试。

此外,您可以考虑使用@RabbitListenerTest来{em>监视您的@RabbitListener调用,而不会干扰您的生产代码。

更多信息,请参见参考手册:https://docs.spring.io/spring-amqp/docs/2.1.4.RELEASE/reference/#test-harness

答案 1 :(得分:0)

  • 给@RabbitListener一个id
  • RabbitListenerEndpointRegistry.getListenerContainer(id);
  • 将容器投射到AbstractMessageListenerContainer
  • container.getMessageListener()
  • 将监听器广播到ChannelAwareMessageListener
  • 致电onMessage()
  • 使用模拟频道并验证预期的通话

编辑

@Autowired
private RabbitListenerEndpointRegistry registry;

@Test
public void test() throws Exception {
    AbstractMessageListenerContainer listenerContainer =
            (AbstractMessageListenerContainer) this.registry.getListenerContainer("foo");
    ChannelAwareMessageListener listener =
            (ChannelAwareMessageListener) listenerContainer.getMessageListener();
    Channel channel = mock(Channel.class);
    listener.onMessage(new Message("foo".getBytes(),
            MessagePropertiesBuilder
                .newInstance()
                .setDeliveryTag(42L)
                .build()), channel);
    verify(channel).basicAck(42L, false);
}

EDIT2

您的json看起来不像DTO,而是看起来像Map<String, DTO>

这对我来说很好...

@SpringBootApplication
public class So55188061Application {

    public static void main(String[] args) {
        SpringApplication.run(So55188061Application.class, args);
    }

    @RabbitListener(id = "foo", queues = "foo")
    public void listen(Map<String, Foo> in, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
        System.out.println(in);
        channel.basicAck(tag, false);
    }

    @Bean
    public MessageConverter converter() {
        return new Jackson2JsonMessageConverter();
    }

    public static class Foo {

        private HashMap<String, Object> inputMap = new HashMap<String, Object>();

        private HashMap<String, Object> outputMap = new HashMap<String, Object>();


        public HashMap<String, Object> getInputMap() {
            return this.inputMap;
        }


        public void setInputMap(HashMap<String, Object> inputMap) {
            this.inputMap = inputMap;
        }


        public HashMap<String, Object> getOutputMap() {
            return this.outputMap;
        }


        public void setOutputMap(HashMap<String, Object> outputMap) {
            this.outputMap = outputMap;
        }


        @Override
        public String toString() {
            return "Foo [inputMap=" + this.inputMap + ", outputMap=" + this.outputMap + "]";
        }

    }

}

@RunWith(SpringRunner.class)
@SpringBootTest
public class So55188061ApplicationTests {

    public final String sampleMessage =
                "{\"ORCH_KEY\":{\"inputMap\":{},"
            + "\"outputMap\":{\"activityId\":\"10001002\",\"activityStatus\":\"SUCCESS\"}}}";

    @Autowired
    private RabbitListenerEndpointRegistry registry;

    @Test
    public void test() throws Exception {
        AbstractMessageListenerContainer listenerContainer = (AbstractMessageListenerContainer) this.registry
                .getListenerContainer("foo");
        ChannelAwareMessageListener listener = (ChannelAwareMessageListener) listenerContainer.getMessageListener();
        Channel channel = mock(Channel.class);
        listener.onMessage(MessageBuilder.withBody(sampleMessage.getBytes())
                .andProperties(MessagePropertiesBuilder.newInstance()
                        .setContentType("application/json")
                        .setDeliveryTag(42L)
                        .build())
                .build(),
                channel);
        verify(channel).basicAck(42L, false);
    }

}

{ORCH_KEY=Foo [inputMap={}, outputMap={activityId=10001002, activityStatus=SUCCESS}]}