在骆驼单元测试中的存根 jms 端点上设置 JMSMessageID

Setting JMSMessageID on stubbed jms endpoints in camel unit tests

我有一条正在测试的路线。我使用 stub://jms:queue:whatever 到 send/receive 消息并扩展 CamelTestSupport 用于我的测试 类。我遇到了一个问题,其中一个路由有一个 bean,它使用幂等 repo 通过“消息 id”存储消息,它从 exchange 读取和存储 JMSMessageID 属性。

我 运行 遇到的问题是我想不出一种方法来对在存根端点上发送的消息设置此 属性。每次调用需要此 prop 的方法时,id returns null 并且我必须将其作为空指针处理。我可以这样做,但最干净的方法是只在测试消息上设置 header。我在端点上尝试了 includeSentJMSMessageId=true,我尝试在生产者上使用 sendBodyAndHeader 并在参数中传递 "JMSMessageID", "ID: whatever",似乎没有用?我读到 driver/connectionfactory 应该设置 header,但我不太熟悉 how/where 来执行此操作。因为我使用的是存根端点,所以我没有在我的 uts 中创建任何 brokers/connectionfactories。

JMSMessageID 只能由提供商设置。它不能由客户端设置,尽管 javax.jms.MessagesetJMSMessageId(). As the JavaDoc 状态:

This method is for use by JMS providers only to set this field when a message is sent. This message cannot be used by clients to configure the message ID. This method is public to allow a JMS provider to set this field when sending a message whose implementation is not its own.

所以不要研究 JMS 组件,用处理器替换它,然后在处理器中添加首选的 JMSMessageID。

类似这样的代码:


  @Test
    void testIdempotency() throws Exception {
        mockOut.expectedMinimumMessageCount(1);
        //specify the route to test
        AdviceWithRouteBuilder.adviceWith(context, "your-route-name", enrichRoute -> {
            //replace the from with a end point we can call directly.
            enrichRoute.replaceFromWith("direct:start");

            //replace the jms endpoint with a processor so it can act as the JMS Endpoint.
            enrichRoute.weaveById("jms:queue:whatever").replace().process(new Processor() {
                @Override
                public void process(Exchange exchange) throws Exception {
                    //Set that ID to the one I want to test
                    exchange.getIn().setHeader("JMSMEssageID", "some-value-to-test");
                }
            });
            // add an endpoint at the end to check if received a mesage

            enrichRoute.weaveAddLast().to(mockOut);

        });
        context.start();
        //send some message
        Map<String,Object> sampleMsg = getSampleMessageAsHashMap("REQUEST.json");
        //get the response
        Map<String,Object> response = (Map<String,Object>)template.requestBody("direct:start", sampleMsg);
        // you will need to check if the response is what you expected.
        // Check the headers etc.
        mockOut.assertIsSatisfied();
    }