【问题标题】:Camel: How to mock a route with two endpoints骆驼:如何模拟具有两个端点的路线
【发布时间】:2020-02-07 05:16:59
【问题描述】:

我是 Camel 的新手,我需要了解如何对具有两个端点的路由进行单元测试。第一个端点获取用户 ID 并将其用于第二个端点。

public RouteBuilder routeBuilder() {
    return new RouteBuilder() {
        @Override
        public void configure() throws HttpOperationFailedException {
            this.from(MyServiceConstant.ROUTE)
                    .setHeader(...)
                    .setHeader(...)
                    .to(MyConstants.THE_FIRST_ROUTE)
                    .setHeader(...)
                    .setHeader(...)
                    .process(...)
                    .setProperty(...)
                    .to(MyConstants.THE_SECOND_ROUTE)
        }
    };
}

所以我必须在我的测试类中同时模拟 MyConstants.THE_FIRST_ROUTE 和 MyConstants.THE_SECOND_ROUTE。我这样做了,但不确定如何编写测试。我所做的只是达到第二个端点,但不知道如何触发第一个端点。

@Produce(uri = MyServiceConstant.ROUTE)
private MyService myService;

@EndpointInject(uri = "mock:" + MyConstants.THE_FIRST_ROUTE)
private MockEndpoint mockFirstService;

@EndpointInject(uri = ""mock:" + MyConstants.THE_SECOND_ROUTE)
private MockEndpoint mockSecondService;

@Test
@DirtiesContext
public void getDetails()throws Exception {

    // **The missing part**: Is this the right way to call my first service? 
    this.mockFirstService.setUserId("123456");

    // this returns a JSON that I'll compare the service response to
    this.mockSecondService.returnReplyBody(...PATH to JSON file);

    UserDetail userDetailsInfo = this.myService.getUserDetails(...args)

    // all of my assertions
    assertEquals("First name", userDetailsInfo.getFirstName());

    MockEndpoint.assertIsSatisfied();
}

【问题讨论】:

  • 通常,如果您与MockEndpoint 合作,您就是define certain expectations,然后通过assertIsSatisfied()(或其兄弟姐妹之一)检查您的期望是否成立。如果其中一个路由调用外部服务,例如 HTTP 服务,则编织路由并将 .to(...) 替换为一些预定义的响应(假设调用的路由不是 INONLY)或添加虚假服务可能会有所帮助连接到

标签: java unit-testing apache-camel spring-camel


【解决方案1】:

这是 Mock 组件的单元测试用例的link。它展示了如何使用mock: 端点和CamelTestSupport 实现测试。 @Roman Vottner 在他的评论中完全正确。

This test case 可能会让您特别感兴趣,因为它展示了如何将smtp: 端点与mock: 端点交换。此外,here 是关于如何模拟现有端点的官方文档(像使用测试探针一样使用它们)。

警告:请记住,在该地区,Camel 3.0 API 与 Camel 2.x API 完全不同。祝你好运!

【讨论】:

  • 感谢您的帮助。我正在使用 camel-test-spring 库没有问题。我不想改变使用 CamelTestSupport 重写我的测试用例。我能够成功调用我模拟的第二个端点。我只是不知道如何测试有 2 个端点的路由。
  • 对不起。我错过了重要的camel-test-spring 细节。但是,在模拟端点上设置期望值和在现有路由上使用 adviceWith 以附加 mock 探针的基本概念保持不变。就像这样 1. 您需要在模拟端点上定义您的期望(Roman 评论中的链接)。 2. 使用adviceWith 将模拟端点连接到您的路由中,拦截 MyConstants.THE_FIRST_ROUTE 和 MyConstants.THE_SECOND_ROUTE 3. 将消息传递到路由 4. 对MockEndpoint.assertIsSatisfied(); 的普通调用不幸的是我找不到任何指向的示例。跨度>
  • 感谢您的帮助。非常感谢。
  • @fumeng this thread 可能包含一些关于如何设置和编织路线的某些元素的有用提示。尤其是给北SHoko 的示例提示了如何将MockEndpoint 与路线建议结合起来
【解决方案2】:

我今天有时间快速破解一些演示代码,使用 Camel Spring 启动原型。开始了。我的路线从 timer 组件生成消息。不使用到端点的显式传递。

//Route Definition - myBean::saySomething() always returns String "Hello World"
@Component
public class MySpringBootRouter extends RouteBuilder {

    @Override
    public void configure() {
        from("timer:hello?period={{timer.period}}").routeId("hello_route")
            .transform().method("myBean", "saySomething")
            .to("log:foo")
                .setHeader("test_header",constant("test"))
            .to("log:bar");
    }

}

@RunWith(CamelSpringBootRunner.class)
@SpringBootTest
public class MySpringBootRouterTest {

    @Autowired
    SpringCamelContext defaultContext;

    @EndpointInject("mock:foo")
    private MockEndpoint mockFoo;
    @EndpointInject("mock:bar")
    private MockEndpoint mockBar;

    @Test
    @DirtiesContext
    public void getDetails() throws Exception {
        assertNotNull(defaultContext);
        mockBar.expectedHeaderReceived("test_header", "test");
        mockBar.expectedMinimumMessageCount(5);
        MockEndpoint.setAssertPeriod(defaultContext, 5_000L);
        MockEndpoint.assertIsSatisfied(mockFoo, mockBar);
        mockFoo.getExchanges().stream().forEach( exchange -> assertEquals(exchange.getIn().getBody(),"Hello World"));

        //This works too
        //mockBar.assertIsSatisfied();
        //mockFoo.assertIsSatisfied();
    }

    @Before
    public void attachTestProbes() throws Exception {
        //This is Camel 3.0 API with RouteReifier
        RouteReifier.adviceWith(defaultContext.getRouteDefinition("hello_route"), defaultContext, new AdviceWithRouteBuilder() {
            @Override
            public void configure() throws Exception {
           //Hook into the current route, intercept log endpoints and reroute them to mock
                interceptSendToEndpoint("log:foo").to("mock:foo");
                interceptSendToEndpoint("log:bar").to("mock:bar");
            }
        });
    }

}

对未来访问者的警告:这里的测试用例演示了如何用mock: 拦截log: 端点并对其设置期望。测试用例可能没有测试任何有价值的东西。

【讨论】:

  • 请注意,只要您只有一个测试用例,此设置就可以工作。如果在同一上下文中有多个测试用例,您的路线将被编织多次,如果您对模拟执行某些期望,这可能会令人困惑。一般来说,每个上下文只执行一次路由编织会更安全。
  • 这太棒了 - 非常感谢这个例子!
猜你喜欢
  • 1970-01-01
  • 2011-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-30
  • 1970-01-01
相关资源
最近更新 更多