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

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

我在编写可工作的骆驼弹簧启动单元测试时遇到了一些麻烦,该测试可以测试简单的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.

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

spring-boot unit-testing kotlin apache-camel mockito
1个回答
0
投票

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

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

TL; DR

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

seda:
  1. 您需要修改您的路线构建器代码以为该路线分配ID(例如Mockito.verify()
  2. 用直接组件替换路由开始处的SNMP组件
  3. 将测试消息传递到AdviceWithRouteBuilder.adviceWith(context, "route-id", routeBuilder -> { routeBuilder.replaceFromWith("direct:snmp-from"); //Replaces the from part of the route `route-id` with a direct component }); 组件而不是SNMP

TL; DR结束。

下面的完整示例代码。

PojoRepo.java

route-id

SNMPDummyRoute.java

direct:

SNMPDummyRoteTest.java

注意:此类使用@Component public class PojoRepo { public void save(String body){ System.out.println(body); } } 而不是扩展@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"); } } ,但核心思想是相同的。

CamelSpringBootRunner

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

CamelTestSupport
© www.soinside.com 2019 - 2024. All rights reserved.