Apache Camel Springboot 测试:AssertionError:mock://checks 收到的消息计数。预期:<1> 但实际是:<0>

问题描述 投票:0回答:1

我在 Spring Boot 应用程序中有以下路线


@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)



spring-boot apache-camel spring-boot-test spring-camel camel-spring-dsl
1个回答
0
投票

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

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

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

context.start();

您需要将模拟端点更改为下面的内容,因为您想模拟 bean-validator 端点

@EndpointInject("mock://bean-validator://checks")
MockEndpoint validationEndpoint;
© www.soinside.com 2019 - 2024. All rights reserved.