如何使用ApacheCamel对同一路由进行多次单元测试

64jmpszr  于 2023-03-08  发布在  Apache
关注(0)|答案(1)|浏览(159)

我正在使用CamelTestSupport,目前有1个路由的2个单元测试。这两个单元测试都是为了测试是否抛出异常,我使用AdviceWith替换并抛出异常。
如文档中所述,问题出现,建议仅通知路线一次,因为这将导致第二次单元测试与路线不匹配。
在每次单元测试后,我可以做些什么来重置路由?

9gm1akwq

9gm1akwq1#

如文档中所述,问题出现,建议仅通知路线一次,因为这将导致第二次单元测试与路线不匹配。
文档中的哪个地方读起来像这样?
使用AdviceWith在不同的单元测试中修改同一路由看起来工作得很好。您还应该能够在同一单元测试中修改同一路由两次或更多次,只要修改不相互冲突。
然而,当在用@BeforeAll@BeforeEach注解的方法中使用AdviceWith时,我会避免或至少非常小心,因为这些更改将应用于每个测试。

示例

package com.example;

import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.AdviceWith;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit5.CamelTestSupport;
import org.junit.jupiter.api.Test;

public class MultiAdviceWithExampleTests extends CamelTestSupport {

    class ExceptionA extends Exception {}
    class ExceptionB extends Exception {}

    @Test
    public void exampleThrowsExceptionA() throws Exception{

        AdviceWith.adviceWith(context, "example", builder -> {

            builder.weaveByToUri("direct:replaceMe")
                .replace()
                .log("Throwing Exception A")
                .throwException(new ExceptionA());
        });

        MockEndpoint exceptionAMockEndpoint = getMockEndpoint("mock:exceptionA");
        MockEndpoint exceptionBMockEndpoint = getMockEndpoint("mock:exceptionB");
        exceptionAMockEndpoint.expectedMessageCount(1);
        exceptionBMockEndpoint.expectedMessageCount(0);

        startCamelContext();
        template.sendBody("direct:example", null);

        exceptionBMockEndpoint.assertIsSatisfied();
        exceptionAMockEndpoint.assertIsSatisfied();
    }

    @Test
    public void exampleThrowsExceptionB() throws Exception{

        AdviceWith.adviceWith(context, "example", builder -> {

            builder.weaveByToUri("direct:replaceMe")
                .replace()
                .log("Throwing Exception B")
                .throwException(new ExceptionB());
        });

        MockEndpoint exceptionAMockEndpoint = getMockEndpoint("mock:exceptionA");
        MockEndpoint exceptionBMockEndpoint = getMockEndpoint("mock:exceptionB");
        exceptionAMockEndpoint.expectedMessageCount(0);
        exceptionBMockEndpoint.expectedMessageCount(1);
        
        startCamelContext();
        template.sendBody("direct:example", null);

        exceptionAMockEndpoint.assertIsSatisfied();
        exceptionBMockEndpoint.assertIsSatisfied();
    }

    @Override
    protected RoutesBuilder createRouteBuilder() throws Exception {
        
        return new RouteBuilder() {

            @Override
            public void configure() throws Exception {
                
                from("direct:example")
                    .id("example")
                    .onException(ExceptionA.class)
                        .log("Caught exception A")
                        .to("mock:exceptionA")
                        .handled(true)
                    .end()
                    .onException(ExceptionB.class)
                        .log("Caught exception A")
                        .to("mock:exceptionB")
                        .handled(true)
                    .end()
                    .to("direct:replaceMe")
                ;
                
                from("direct:replaceMe")
                    .routeId("replaceMe")
                    .log("should not be displayed.");
            }
            
        };
    }

    @Override
    public boolean isUseAdviceWith() {
        return true;
    }
}

由于覆盖isUseAdviceWith方法以返回true会强制用户为每个测试手动启动camel上下文,因此我假设camel-tests-support要么为每个测试创建单独的上下文和路由,要么至少在测试之间将路由和模拟端点重置为其原始状态。
两个单元测试都是为了测试是否抛出异常,我使用AdviceWith替换并抛出异常。
如果你使用的是JUnits assertThrows,它可能不会像你期望的那样在Apache Camel中工作,因为Camel可能会抛出它自己的一个异常。要获得原始异常,你可以使用template.send,并通过.getException().getClass()从结果交换中获得结果异常。

// Remove the onException blocks from route with this 
// or getException() will return null
Exchange result = template.send("direct:example", new DefaultExchange(context));
assertEquals(ExceptionB.class, result.getException().getClass());

相关问题