代码之家  ›  专栏  ›  技术社区  ›  manish2aug

Apache Camel Springboot测试:断言错误:mock://checks收到的消息计数。预期:<1>,但实际为:<0>

  •  0
  • manish2aug  · 技术社区  · 2 年前

    我在春季启动应用程序中有以下路线

    
    @Slf4j
    @Component
    public class LogRoute extends RouteBuilder {
    
        @Override
        public void configure() {
    
            from("direct:log")
                    .routeId("direct-log-route")
                    .log(LoggingLevel.INFO, "Message picked up by direct-log-route ${body}")
                    .split(body().tokenize("\n"))
                    .setProperty("originalBody", body())
                    .unmarshal()
                    .json(JsonLibrary.Jackson, LogEvent.class)
                    .log(LoggingLevel.INFO, "Message formatted as LogEvent ${body}")
                    .process(exchange ->
                            exchange.getIn()
                                    .getBody(LogEvent.class)
                                    .setEvent_object(exchange.getProperty(
                                            "originalBody", String.class)))
                    .to("bean-validator://checks")
                    .log(LoggingLevel.INFO, "Validation completed successfully ${body}")
                    .to("jpa:test.log.LogEvent")
                    .log(LoggingLevel.INFO, "Inserted log event ${body.id}");
        }
    
    }
    
    

    并进行以下测试

    @CamelSpringBootTest
    @EnableAutoConfiguration
    @SpringBootTest(
            webEnvironment = SpringBootTest.WebEnvironment.NONE,
            properties = {
                    "camel.springboot.java-routes-include-pattern=**/LogRoute*"
            },
            classes = {LogRoute.class}
    )
    @ActiveProfiles("test")
    @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
    @DisableJmx
    public class LogRouteTest {
    
        @Produce("direct:log")
        ProducerTemplate producerTemplate;
    
        @EndpointInject("mock://checks")
        MockEndpoint validationEndpoint;
    
        @EndpointInject("mock:test.log.LogEvent")
        MockEndpoint jpaMockEndpoint;
    
        @Autowired
        private CamelContext context;
    
        @BeforeEach
        public void setup() {
            context.setTracing(true);
        }
    
        @Test
        public void shouldAutowireProducerTemplate() {
            assertNotNull(producerTemplate);
        }
    
        @Test
        public void invalidJsonMessage() throws InterruptedException {
            validationEndpoint.expectedMessageCount(0);
            jpaMockEndpoint.expectedMessageCount(0);
    
            CamelExecutionException camelExecutionException =
                    assertThrows(CamelExecutionException.class,
                            () -> producerTemplate
                                    .sendBody(
                                            "direct:log",
                                            "msg"));
            boolean condition = camelExecutionException.getCause() instanceof JsonParseException;
    
            assertTrue(condition);
            jpaMockEndpoint.assertIsSatisfied();
            validationEndpoint.assertIsSatisfied();
        }
    
        @Test
        public void validJsonWithNoContent() throws InterruptedException {
            NotifyBuilder notify =
                    new NotifyBuilder(context).whenDone(1).create();
    
            validationEndpoint.expectedMessageCount(1);
            validationEndpoint.expectedBodyReceived();
            validationEndpoint.expectedNoHeaderReceived();
            validationEndpoint.setLog(true);
            jpaMockEndpoint.expectedMessageCount(0);
    
            CamelExecutionException camelExecutionException =
                    assertThrows(CamelExecutionException.class,
                            () -> producerTemplate
                                    .sendBody("direct:log", "{}"));
    
    
            List<Exchange> exchanges = jpaMockEndpoint.getExchanges();
            System.out.println(">>>>>>>"+exchanges.size());
            System.out.println(">>>>>>>"+context.getRegistry());
            System.out.println(">>>>>>>"+context.getRegistry().toString());
            System.out.println(">>>>>>>"+context.getRoutes());
            System.out.println(">>>>>>>"+context.getEndpoints());
            System.out.println(">>>>>>>"+context.getComponentNames());
            System.out.println(">>>>>>>"+context.getEndpointRegistry());
            System.out.println(">>>>>>>"+context.getRoutesSize());
            System.out.println(">>>>>>>"+context.getTypeConverter());
            System.out.println(">>>>>>>"+context.getValidatorRegistry());
    
            validationEndpoint.assertIsSatisfied(100);
            jpaMockEndpoint.assertIsSatisfied(100);
        }
    }
    
    

    第二个测试的目的是验证如果将消息“{}”发送到direct:log端点,它将超出to(bean-validator://checks)当我实时尝试时,它会在路由中的第二个端点上失败。

    invalidJsonMessage()测试验证异常是否发生在第一个bean验证器端点,因此验证模拟端点应接收0条消息。

    validJsonWithNoContent()测试定义了2个模拟端点,一个用于bean验证器,另一个用于jpa组件。它希望验证端点接收一条消息,jpa在该组件上失败时接收0条消息。

    当测试类运行时,第一个测试invalidJsonMessage()通过,但第二个测试validJsonWithNoContent()失败。这是日志

    2023-09-09T14:26:38.032+02:00  INFO 42584 --- [           main] c.t.s.j.CamelSpringBootExecutionListener : CamelSpringBootExecutionListener before: class momentum.retail.security.auth0.streams.log.LogRouteTest.validJsonWithNoContent
    2023-09-09T14:26:38.033+02:00  INFO 42584 --- [           main] c.t.s.j.CamelSpringBootExecutionListener : Initialized CamelSpringBootExecutionListener now ready to start CamelContext
    2023-09-09T14:26:38.033+02:00  INFO 42584 --- [           main] o.a.c.t.s.j.CamelAnnotationsHandler      : Starting CamelContext with name [camelContext].
    2023-09-09T14:26:38.093+02:00  INFO 42584 --- [           main] o.a.c.support.LifecycleStrategySupport   : Autowired property: validatorFactory on component: bean-validator as exactly one instance of type: jakarta.validation.ValidatorFactory (org.springframework.validation.beanvalidation.LocalValidatorFactoryBean) found in the registry
    2023-09-09T14:26:38.100+02:00  INFO 42584 --- [           main] o.a.camel.component.jpa.JpaComponent     : Using EntityManagerFactory found in registry with id [entityManagerFactory] org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@4c7b4a31
    2023-09-09T14:26:38.100+02:00  INFO 42584 --- [           main] o.a.c.c.jpa.DefaultTransactionStrategy   : Using TransactionManager found in registry with id [transactionManager] org.springframework.orm.jpa.JpaTransactionManager@38320819
    2023-09-09T14:26:38.124+02:00  INFO 42584 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Apache Camel 4.0.0 (camel-1) is starting
    2023-09-09T14:26:38.127+02:00  INFO 42584 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Routes startup (started:1)
    2023-09-09T14:26:38.128+02:00  INFO 42584 --- [           main] o.a.c.impl.engine.AbstractCamelContext   :     Started direct-log-route (direct://log)
    2023-09-09T14:26:38.128+02:00  INFO 42584 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Apache Camel 4.0.0 (camel-1) started in 3ms (build:0ms init:0ms start:3ms)
    2023-09-09T14:26:38.561+02:00  INFO 42584 --- [           main] direct-log-route                         : Message picked up by direct-log-route {}
    2023-09-09T14:26:38.599+02:00  INFO 42584 --- [           main] direct-log-route                         : Message formatted as LogEvent LogEvent(id=null, logId=null, logDate=null, logType=null, description=null, ipAddress=null, clientName=null, event_object=null)
    2023-09-09T14:26:38.601+02:00  INFO 42584 --- [           main] direct-log-route                         : Validation completed successfully LogEvent(id=null, logId=null, logDate=null, logType=null, description=null, ipAddress=null, clientName=null, event_object={})
    2023-09-09T14:26:38.662+02:00  WARN 42584 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 42804
    2023-09-09T14:26:38.662+02:00 ERROR 42584 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : ERROR: column "event_obj" is of type json but expression is of type character varying
      Hint: You will need to rewrite or cast the expression.
      Position: 116
    2023-09-09T14:26:38.667+02:00 ERROR 42584 --- [           main] o.a.c.p.e.DefaultErrorHandler            : Failed delivery for (MessageId: B22C94B2D01F6BC-0000000000000001 on ExchangeId: B22C94B2D01F6BC-0000000000000001). Exhausted after delivery attempt: 1 caught: org.hibernate.exception.SQLGrammarException: could not execute statement [ERROR: column "event_obj" is of type json but expression is of type character varying
      Hint: You will need to rewrite or cast the expression.
      Position: 116] [insert into "LOGS".log_event (client_name,description,event_obj,ip_address,log_date,log_id,log_type) values (?,?,?,?,?,?,?)]
    
    Message History (source location and message history is disabled)
    ---------------------------------------------------------------------------------------------------------------------------------------
    Source                                   ID                             Processor                                          Elapsed (ms)
                                             direct-log-route/direct-log-ro from[direct://log]                                    264835460
        ...
                                             direct-log-route/to2           jpa:test.log.Log            0
    
    Stacktrace
    ---------------------------------------------------------------------------------------------------------------------------------------
    
    org.hibernate.exception.SQLGrammarException: could not execute statement [ERROR: column "event_obj" is of type json but expression is of type character varying
      Hint: You will need to rewrite or cast the expression.
      Position: 116] [insert into "LOGS".log_event (client_name,description,event_obj,ip_address,log_date,log_id,log_type) values (?,?,?,?,?,?,?)]
        at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:89) ~[hibernate-core-6.2.6.Final.jar:6.2.6.Final]
        
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.9.3.jar:1.9.3]
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.9.3.jar:1.9.3]
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.9.3.jar:1.9.3]
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.9.3.jar:1.9.3]
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.3.jar:1.9.3]
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.9.3.jar:1.9.3]
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.9.3.jar:1.9.3]
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.9.3.jar:1.9.3]
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.3.jar:1.9.3]
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.9.3.jar:1.9.3]
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.9.3.jar:1.9.3]
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.9.3.jar:1.9.3]
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.9.3.jar:1.9.3]
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.9.3.jar:1.9.3]
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursiv~[idea_rt.jar:na]
        at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) ~[junit-rt.jar:na]
        at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) ~[junit-rt.jar:na]
        at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) ~[junit-rt.jar:na]
    Caused by: org.postgresql.util.PSQLException: ERROR: column "event_obj" is of type json but expression is of type character varying
      Hint: You will need to rewrite or cast the expression.
      Position: 116
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2713) ~[postgresql-42.6.0.jar:42.6.0]
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2401) ~[postgresql-42.6.0.jar:42.6.0]
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:368) ~[postgresql-42.6.0.jar:42.6.0]
        at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:498) ~[postgresql-42.6.0.jar:42.6.0]
        at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:415) ~[postgresql-42.6.0.jar:42.6.0]
        at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:190) ~[postgresql-42.6.0.jar:42.6.0]
        at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:152) ~[postgresql-42.6.0.jar:42.6.0]
        at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) ~[HikariCP-5.0.1.jar:na]
        at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) ~[HikariCP-5.0.1.jar:na]
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:275) ~[hibernate-core-6.2.6.Final.jar:6.2.6.Final]
        ... 130 common frames omitted
    
    >>>>>>>0
    >>>>>>>org.apache.camel.support.DefaultRegistry@1c6ab85
    >>>>>>>org.apache.camel.support.DefaultRegistry@1c6ab85
    >>>>>>>[Route[direct://log -> null]]
    >>>>>>>[direct://log, bean-validator://checks, mock://checks, mock://test.log.LogEvent, jpa://test.log.LogEvent]
    >>>>>>>[bean-validator, direct, mock, jpa, bean, spring-event]
    >>>>>>>EndpointRegistry for camel-1 [capacity: 1000]
    >>>>>>>1
    >>>>>>>org.apache.camel.impl.converter.DefaultTypeConverter@100d071
    >>>>>>>ValidatorRegistry for camel-1 [capacity: 1000]
    2023-09-09T14:26:38.673+02:00  INFO 42584 --- [           main] o.a.camel.component.mock.MockEndpoint    : Asserting: mock://checks is satisfied
    2023-09-09T14:26:48.678+02:00  WARN 42584 --- [           main] o.a.camel.component.mock.MockEndpoint    : The latch did not reach 0 within the specified time
    2023-09-09T14:26:48.718+02:00  INFO 42584 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Apache Camel 4.0.0 (camel-1) is shutting down (timeout:10s)
    2023-09-09T14:26:48.723+02:00  INFO 42584 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Routes stopped (stopped:1)
    2023-09-09T14:26:48.724+02:00  INFO 42584 --- [           main] o.a.c.impl.engine.AbstractCamelContext   :     Stopped direct-log-route (direct://log)
    2023-09-09T14:26:48.725+02:00  INFO 42584 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Apache Camel 4.0.0 (camel-1) shutdown in 7ms (uptime:10s)
    2023-09-09T14:26:48.730+02:00  INFO 42584 --- [           main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
    2023-09-09T14:26:48.734+02:00  INFO 42584 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
    2023-09-09T14:26:48.736+02:00  INFO 42584 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
    2023-09-09T14:26:48.737+02:00  INFO 42584 --- [           main] m.r.s.auth0.streams.log.LogRouteTest     : ********************************************************************************
    2023-09-09T14:26:48.737+02:00  INFO 42584 --- [           main] m.r.s.auth0.streams.log.LogRouteTest     : Testing done: validJsonWithNoContent (test.log.LogRouteTest)
    2023-09-09T14:26:48.737+02:00  INFO 42584 --- [           main] m.r.s.auth0.streams.log.LogRouteTest     : Took: 10s610ms (10610 millis)
    2023-09-09T14:26:48.737+02:00  INFO 42584 --- [           main] m.r.s.auth0.streams.log.LogRouteTest     : ********************************************************************************
    2023-09-09T14:26:48.737+02:00  INFO 42584 --- [           main] c.t.s.j.CamelSpringBootExecutionListener : CamelSpringBootExecutionListener after: class test.log.LogRouteTest.validJsonWithNoContent
    
    java.lang.AssertionError: mock://checks Received message count. Expected: <1> but was: <0>
    Expected :<1>
    Actual   :<0>
    <Click to see difference>
    
    
        at org.apache.camel.component.mock.MockEndpoint.fail(MockEndpoint.java:1860)
        at org.apache.camel.component.mock.MockEndpoint.assertEquals(MockEndpoint.java:1794)
        at org.apache.camel.component.mock.MockEndpoint.doAssertIsSatisfied(MockEndpoint.java:448)
        at org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied(MockEndpoint.java:426)
        at test.log.LogRouteTest.validJsonWithNoContent(LogRouteTest.java:107)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
        at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
        at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
        at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
        at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
        at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
    
    
    
    
    0 回复  |  直到 2 年前
        1
  •  0
  •   Vignesh Nayak Manel    2 年前

    您可以使用AdviceWith来模拟端点,方法是在测试类上使用@UseAdviceWith注释,然后拦截bean验证器端点以发送到模拟端点。请注意,如果您使用AdviceWith,则需要启动上下文。

    此外,由于您不希望端点中有标头,因此需要删除在拦截端点时添加的CamelInterceptedEndpoint标头。

    AdviceWith.adviceWith(context, "direct-log-route", a -> {
            a.interceptSendToEndpoint("bean-validator://checks").removeHeader("CamelInterceptedEndpoint").to("mock:bean-validator://checks");
    });
    
    context.start();
    

    您需要将模拟端点更改为以下内容,因为您想模拟bean验证器端点

    @EndpointInject("mock://bean-validator://checks")
    MockEndpoint validationEndpoint;