Apache Camel SNMP路由的简单单元测试

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

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模拟从来没有任何交互:

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.

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

msgl88 回答:Apache Camel SNMP路由的简单单元测试

现在我知道这里发生了什么! 您的受测试的RouteBuilder有一个from("snmp")。如果希望在此处传递模拟消息以进行测试,则需要在测试执行过程中将snmp:组件与direct:seda:组件交换。

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

TL; DR

假设您正在使用Apache Camel 3.x,请按以下步骤操作。我不太会Kotlin,因此,我将向您展示如何在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. 将测试消息而不是SNMP传递到direct:组件

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,但是核心思想是相同的。


@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片段。

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,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
本文链接:https://www.f2er.com/3123938.html

大家都在问