【问题标题】:Writing unit tests for camel routes in a SpringBoot application - getting messageCount 0在 Spring Boot 应用程序中为骆驼路由编写单元测试 - 获取消息计数 0
【发布时间】:2019-04-04 03:13:32
【问题描述】:

我正在尝试为骆驼路线编写单元测试 - 它用于导入和处理文件

from(fullImportFTP)
        .routeId(STUB_FILE_DOWNLOAD_ROUTE_ID)
        .onException(Exception.class)
        .handled(false)
        .log(LoggingLevel.ERROR, STUB_IMPORT_ERROR_CODE)
        .end()
        .log("Processing  Stub file:[${header.CamelFileName}]")
        .to(ROUTE_TO_MACE);

from(ROUTE_TO_MACE)
        .routeId(STUB_FILE_IMPORT_ROUTE_ID)
        .onException(Exception.class)
        .handled(false)
        .log(LoggingLevel.ERROR, STUB_IMPORT_ERROR_CODE)
        .end()
        .onException(IOException.class)
        .maximumRedeliveries(routesConfig.camelMaximumRetries).redeliveryDelay(routesConfig.camelRedeliveryDelay)
        .handled(false)
        .log(LoggingLevel.ERROR, STUB_IMPORT_ERROR_CODE)
        .end()
        .split().tokenizeXML(ITEM).streaming()
        .process(processor)
        .to("log:route.StubRoute?level=DEBUG")
        .end()
        .log("Stub file sucessfully processed:[${header.CamelFileName}]");

下面是单元测试:

@RunWith(CamelSpringBootRunner.class)
@SpringBootTest
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class CamelRouteTest {
    @EndpointInject(uri = "mock:success_result")
    private MockEndpoint successResultEndpoint;

    @EndpointInject(uri = "direct:mock-import-stub-download")
    private FluentProducerTemplate producer;

    @Autowired
    private CamelContext camelContext;

    @MockBean
    RestTemplate restTemplate;


    private static final String MOCK_IMPORT_STUB_DOWNLOAD = "direct:mock-import-stub-download";
    private static final String TEST_STUB_FILE_LOCATION = "src/test/resources";

    @Before
    public void setup() throws Exception {
        camelContext.getRouteDefinition(STUB_FILE_DOWNLOAD_ROUTE_ID).autoStartup(true).adviceWith(camelContext,
                new AdviceWithRouteBuilder() {
                    @Override
                    public void configure() throws Exception {
                        replaceFromWith(MOCK_IMPORT_STUB_DOWNLOAD);
                        interceptSendToEndpoint("log:route.StubRoute?level=DEBUG").skipSendToOriginalEndpoint().to(successResultEndpoint);
                    }
                });

        camelContext.start();
    }

    @Test
    public void testFileDownloadRouter() throws Exception {
        File file = new File(TEST_STUB_FILE_LOCATION + "/Stub_11092018_162149_59642501.xml");
        successResultEndpoint.expectedMessageCount(1);
        producer.withBody(file).withHeader(Exchange.FILE_NAME, "Stub_24102018_162149_59642501.xml").send();
        successResultEndpoint.assertIsSatisfied();                                                                                                                                                                                                
    }

我总是得到消息计数为 0。这是错误

java.lang.AssertionError: mock://success_result 收到消息 数数。预期: 但为: 预期: 实际:

我在这里做错了什么?如您所见,我有 2 条路线 - 第一条路线实际上是第二条路线,所以在单元测试中我也应该有 2 条路线吗?我没有添加 2 条路由,因为如果我调试,我可以看到它实际上通过了处理器并返回了正确的结果。

【问题讨论】:

    标签: spring-boot apache-camel camel-test


    【解决方案1】:

    首先:你使用的是AdviceWith,所以你应该把注解@UseAdviceWith放在你的testclass上。否则 Camel 上下文的自动启动和路由建议可能会重叠。

    对于 Mock 上缺失的信息:也许您的测试断言太早了。我猜生产者在处理消息时不会阻塞,但 MockEndpoint 断言在发送消息后立即跟随。发送消息后,收到的消息计数仍为 0。

    要检查等待是否有帮助,您可以插入 Thread.sleep()。如果可行,您应该摆脱 Thread.sleep() 并将其替换为 Camel NotifyBuilder

    刚刚看到另一点。 interceptSendToEndpoint 链中的最后一个 to() 指向 MockEndpoint 实例变量。我认为这应该指向 MockEndpoint URI,即.to("mock:success_result")

    还有一个:您可以通过getRouteDefinition(STUB_FILE_DOWNLOAD_ROUTE_ID) 获得第一条建议路径,但在此建议块中,您可以建议两条路径。这可能是你的问题的原因。不建议使用第二条路线,因此您的模拟没有到位。您必须在其自己的建议块中建议第二条路线。

    @Before
    public void setup() throws Exception {
        camelContext.getRouteDefinition(STUB_FILE_DOWNLOAD_ROUTE_ID).autoStartup(true).adviceWith(camelContext, new AdviceWithRouteBuilder() {
            @Override
            public void configure() throws Exception {
                replaceFromWith(MOCK_IMPORT_STUB_DOWNLOAD);
            }
        });
        camelContext.getRouteDefinition(STUB_FILE_IMPORT_ROUTE_ID).autoStartup(true).adviceWith(camelContext, new AdviceWithRouteBuilder() {
            @Override
            public void configure() throws Exception {
                interceptSendToEndpoint("log:route.StubRoute?level=DEBUG").skipSendToOriginalEndpoint().to("mock:success_result");
            }
        });
    
        camelContext.start();
    }
    

    【讨论】:

    • 我已经添加了 @UseAdviceWith 注释并等待,但不幸的是它仍然失败..
    • 将 interceptEndPoint 也更改为 URI ,再次失败.. 不知道这是否有用,但我可以在日志中看到 - "camel.component.mock.MockEndpoint : Asserting:在路由关闭和错误消息之前模拟://success_result is满足。
    • 是的,这是在检查断言时记录的。不代表满足,就像“Asserting now if mock is满足...”然后错误信息就是结果。
    • 只是为了隔离问题。您可以用模拟端点静态替换日志语句,即以拦截器应该做的方式更改代码并禁用拦截器吗?如果它起作用了,那么拦截器就有问题了。如果仍然无法正常工作,则 Mock 端点无法正常工作。
    • 你必须做两个单独的adviceWith块,请参阅我的扩展答案
    猜你喜欢
    • 2023-01-28
    • 2021-04-30
    • 1970-01-01
    • 1970-01-01
    • 2015-04-24
    • 2018-08-25
    • 2021-06-19
    • 2019-01-24
    • 1970-01-01
    相关资源
    最近更新 更多