本文介绍了Apache Camel SNMP路由的简单单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我在编写一个可以正常工作的骆驼弹簧启动单元测试时遇到了麻烦,该测试可以测试一条简单的SNMP路由.这是我到目前为止的内容:

I'm having some trouble getting a working Camel Spring-Boot unit test written, that tests a simple SNMP route. Here is what I have so far:

SnmpRoute.kt

open class SnmpRoute(private val snmpProperties: SnmpProperties, private val repository: IPduEventRepository) : RouteBuilder() {

    @Throws(Exception::class)
    override fun configure() {

        logger.debug("Initialising with properties [{}]", snmpProperties)

        from("snmp:0.0.0.0:1161?protocol=udp&type=TRAP")
                .process { exchange ->
                    // do stuff
                }
                .bean(repository, "save")
    }
}

SnmpRouteTest.kt

@CamelSpringBootTest
@SpringBootApplication
@EnableAutoConfiguration
open class SnmpRouteTest : CamelTestSupport() {

    object SnmpConstants {
        const val SNMP_TRAP = "<snmp><entry><oid>...datadatadata...</oid><value>123456</value></entry></snmp>"
        const val MOCK_SNMP_ENDPOINT = "mock:snmp"
    }

    @Mock
    lateinit var snmpProperties: SnmpProperties

    @Mock
    lateinit var repository: IPduEventRepository

    @InjectMocks
    lateinit var snmpRoute: SnmpRoute

    @EndpointInject(SnmpConstants.MOCK_SNMP_ENDPOINT)
    lateinit var mock: MockEndpoint

    @Before
    fun setup() {
        initMocks(this)
    }

    @Throws(Exception::class)
    override fun createRouteBuilder(): RouteBuilder {
        return snmpRoute
    }

    @Test
    @Throws(Exception::class)
    fun `Test SNMP endpoint`() {
        mock.expectedBodiesReceived(SnmpConstants.SNMP_TRAP)
        template.sendBody(SnmpConstants.MOCK_SNMP_ENDPOINT,
                          SnmpConstants.SNMP_TRAP)
        mock.assertIsSatisfied()

        verify(repository).save(PduEvent(1234, PDU.TRAP))
    }
}

但是,当我运行此测试时,它失败了,因为repository模拟从来没有任何交互:

However, when I run this test, it fails as the repository mock never has any interactions:

Wanted but not invoked:
repository.save(
    PduEvent(requestId=1234, type=-89)
);
-> at org.meanwhile.in.hell.camel.snmp.route.SnmpRouteTest.Test SNMP endpoint(SnmpRouteTest.kt:61)
Actually, there were zero interactions with this mock.

有人可以帮助我理解为什么无法正确交互吗?手动运行时,它可以正常工作并按预期保存.

Can someone help me understand why this isn't interacting correctly? When run manually, this works and saves as expected.

推荐答案

现在我明白了这里发生了什么!您正在测试的RouteBuilder具有from("snmp").如果希望在此处传递模拟消息以进行测试,则需要将snmp:组件替换为 direct: seda: 组件,在测试执行期间.

Now I see what is going on here!Your RouteBuilder under test has a from("snmp"). If you wish to deliver a mock message there for testing, you need to swap the snmp: component with something like a direct: or seda: component, during test execution.

您当前的测试正在向Mock端点传递一条消息,并验证是否在此处收到了该消息.它不与实际路线构建器交互.这就是您的模拟终结点声明确实通过但Mockito.verify()失败的原因.

Your current test is delivering a message to a Mock endpoint and verifying if it was received there. It does not interact with the real route builder. That's why your mock endpoint assertions do passed but Mockito.verify() failed.

TL; DR

假设您正在使用Apache Camel 3.x,请按以下步骤操作.我不太会Kotlin,因此,我将向您展示如何用Java做到这一点.

Presuming that you are using Apache Camel 3.x, here is how to do it. I'm not fluent in Kotlin so, I'll show how to do that in Java.

AdviceWithRouteBuilder.adviceWith(context, "route-id", routeBuilder -> {
  routeBuilder.replaceFromWith("direct:snmp-from"); //Replaces the from part of the route `route-id` with a direct component
});
  1. 您需要修改您的路线构建器代码以为该路线分配一个ID(例如,route-id)
  2. 在路由开始时用直接组件替换SNMP组件
  3. 将测试消息传递到direct:组件而不是SNMP
  1. You need to modify your route builder code to assign an ID to the route (say, route-id)
  2. Replace the SNMP component at the start of the route with a direct component
  3. Deliver test messages to the direct: component instead of SNMP

TL; DR结束.

下面的完整示例代码.

PojoRepo.java

@Component
public class PojoRepo {

    public void save(String body){
        System.out.println(body);
    }
}

SNMPDummyRoute.java

@Component
public class SNMPDummyRoute extends RouteBuilder {

    PojoRepo pojoRepo;
    public SNMPDummyRoute(PojoRepo pojoRepo) {
        this.pojoRepo = pojoRepo;
    }
    @Override
    public void configure() throws Exception {
        from("snmp:0.0.0.0:1161?protocol=udp&type=TRAP")
                .id("snmp-route")
                .process(exchange -> {
                    exchange.getMessage().setBody(String.format("Saw message [%s]", exchange.getIn().getBody()));
                })
                .to("log:snmp-log")
                .bean(pojoRepo, "save");
    }
}

SNMPDummyRoteTest.java

注意:此类使用CamelSpringBootRunner而不是扩展CamelTestSupport,但是核心思想是相同的.

Note: This class uses CamelSpringBootRunner instead of extending CamelTestSupport, but the core idea is same.


@RunWith(CamelSpringBootRunner.class)
@SpringBootTest
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@DisableJmx(false)
@MockEndpoints("log:*")
public class SNMPDummyRouteTest {

    @MockBean
    PojoRepo repo;

    @EndpointInject("mock:log:snmp-log")
    MockEndpoint mockEndpoint;

    @Produce
    ProducerTemplate testTemplate;

    @Autowired
    CamelContext camelContext;


    @Test
    public void testRoute() throws Exception {

        AdviceWithRouteBuilder.adviceWith(camelContext,"snmp-route",routeBuilder -> {
            routeBuilder.replaceFromWith("direct:snmp-from");
        });

        testTemplate.sendBody("direct:snmp-from","One");
        testTemplate.sendBody("direct:snmp-from","Two");

        mockEndpoint.expectedMinimumMessageCount(2);
        mockEndpoint.setAssertPeriod(2_000L);

        mockEndpoint.assertIsSatisfied();
        Mockito.verify(repo, Mockito.atLeast(2)).save(anyString());
    }

}

下面的测试运行日志.仔细查看SNMP端点与直接组件交换的XML片段.

Logs from test run below. Take a closer look at the XML piece where the SNMP endpoint gets swapped in with a direct component.

2019-11-12 20:52:57.126  INFO 32560 --- [           main] o.a.c.component.snmp.SnmpTrapConsumer    : Starting trap consumer on udp:0.0.0.0/1161
2019-11-12 20:52:58.363  INFO 32560 --- [           main] o.a.c.component.snmp.SnmpTrapConsumer    : Started trap consumer on udp:0.0.0.0/1161 using udp protocol
2019-11-12 20:52:58.364  INFO 32560 --- [           main] o.a.c.s.boot.SpringBootCamelContext      : Route: snmp-route started and consuming from: snmp://udp:0.0.0.0/1161
2019-11-12 20:52:58.368  INFO 32560 --- [           main] o.a.c.s.boot.SpringBootCamelContext      : Total 1 routes, of which 1 are started
2019-11-12 20:52:58.370  INFO 32560 --- [           main] o.a.c.s.boot.SpringBootCamelContext      : Apache Camel 3.0.0-M4 (CamelContext: MyCamel) started in 2.645 seconds
2019-11-12 20:52:59.670  INFO 32560 --- [           main] o.a.c.i.engine.DefaultShutdownStrategy   : Starting to graceful shutdown 1 routes (timeout 10 seconds)
2019-11-12 20:52:59.680  INFO 32560 --- [ - ShutdownTask] o.a.c.component.snmp.SnmpTrapConsumer    : Stopped trap consumer on udp:0.0.0.0/1161
2019-11-12 20:52:59.683  INFO 32560 --- [ - ShutdownTask] o.a.c.i.engine.DefaultShutdownStrategy   : Route: snmp-route shutdown complete, was consuming from: snmp://udp:0.0.0.0/1161
2019-11-12 20:52:59.684  INFO 32560 --- [           main] o.a.c.i.engine.DefaultShutdownStrategy   : Graceful shutdown of 1 routes completed in 0 seconds
2019-11-12 20:52:59.687  INFO 32560 --- [           main] o.a.c.s.boot.SpringBootCamelContext      : Route: snmp-route is stopped, was consuming from: snmp://udp:0.0.0.0/1161
2019-11-12 20:52:59.689  INFO 32560 --- [           main] o.a.c.s.boot.SpringBootCamelContext      : Route: snmp-route is shutdown and removed, was consuming from: snmp://udp:0.0.0.0/1161
2019-11-12 20:52:59.691  INFO 32560 --- [           main] o.apache.camel.builder.AdviceWithTasks   : AdviceWith replace input from [snmp:0.0.0.0:1161?protocol=udp&type=TRAP] --> [direct:snmp-from]
2019-11-12 20:52:59.692  INFO 32560 --- [           main] org.apache.camel.reifier.RouteReifier    : AdviceWith route after: Route(snmp-route)[From[direct:snmp-from] -> [process[Processor@0x589dfa6f], To[log:snmp-log], Bean[org.foo.bar.POJORepo$MockitoMock$868728200]]]
2019-11-12 20:52:59.700  INFO 32560 --- [           main] org.apache.camel.reifier.RouteReifier    : Adviced route before/after as XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<route xmlns="http://camel.apache.org/schema/spring" customId="true" id="snmp-route">
    <from uri="snmp:0.0.0.0:1161?protocol=udp&amp;type=TRAP"/>
    <process id="process1"/>
    <to id="to1" uri="log:snmp-log"/>
    <bean id="bean1" method="save"/>
</route>

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<route xmlns="http://camel.apache.org/schema/spring" customId="true" id="snmp-route">
    <from uri="direct:snmp-from"/>
    <process id="process1"/>
    <to id="to1" uri="log:snmp-log"/>
    <bean id="bean1" method="save"/>
</route>

2019-11-12 20:52:59.734  INFO 32560 --- [           main] .i.e.InterceptSendToMockEndpointStrategy : Adviced endpoint [log://snmp-log] with mock endpoint [mock:log:snmp-log]
2019-11-12 20:52:59.755  INFO 32560 --- [           main] o.a.c.s.boot.SpringBootCamelContext      : Route: snmp-route started and consuming from: direct://snmp-from
2019-11-12 20:52:59.834  INFO 32560 --- [           main] snmp-log                                 : Exchange[ExchangePattern: InOnly, BodyType: String, Body: Saw message [One]]
2019-11-12 20:52:59.899  INFO 32560 --- [           main] snmp-log                                 : Exchange[ExchangePattern: InOnly, BodyType: String, Body: Saw message [Two]]
2019-11-12 20:52:59.900  INFO 32560 --- [           main] o.a.camel.component.mock.MockEndpoint    : Asserting: mock://log:snmp-log is satisfied
2019-11-12 20:53:01.903  INFO 32560 --- [           main] o.a.camel.component.mock.MockEndpoint    : Re-asserting: mock://log:snmp-log is satisfied after 2000 millis
2019-11-12 20:53:01.992  INFO 32560 --- [           main] o.a.c.s.boot.SpringBootCamelContext      : Apache Camel 3.0.0-M4 (CamelContext: MyCamel) is shutting down
2019-11-12 20:53:01.993  INFO 32560 --- [           main] o.a.c.i.engine.DefaultShutdownStrategy   : Starting to graceful shutdown 1 routes (timeout 10 seconds)
2019-11-12 20:53:01.996  INFO 32560 --- [ - ShutdownTask] o.a.c.i.engine.DefaultShutdownStrategy   : Route: snmp-route shutdown complete, was consuming from: direct://snmp-from
2019-11-12 20:53:01.996  INFO 32560 --- [           main] o.a.c.i.engine.DefaultShutdownStrategy   : Graceful shutdown of 1 routes completed in 0 seconds

这篇关于Apache Camel SNMP路由的简单单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-08 22:21