【问题标题】:Object result in Apache Camel junit testApache Camel junit 测试中的对象结果
【发布时间】:2018-02-16 06:47:24
【问题描述】:

我尝试将骆驼输出测试为对象,但无法获取交换对象。这就是它失败的地方Customer resultCustomer = processActs.getExchanges().get(0).getIn().getBody(Customer.class)。请帮我解决这个问题。我提到了这个Right way to test my object in Camel

客户 POJO:

public class Customer {
    private String firstName;
    private String lastName;
   // getters and setters
    @Override
    public String toString(){
        return firstName +":::" + lastName;
    }
}

测试路线:

public class FileTest4 extends CamelTestSupport {

    @EndpointInject(uri = "direct:teststart")
    private Endpoint start;

    @EndpointInject(uri = "mock:direct:processActs")
    private MockEndpoint processActs;

    @EndpointInject(uri = "mock:direct:write2File")
    private MockEndpoint write2File;

    @EndpointInject(uri = "mock:end")
    private MockEndpoint mockEndResult;

    @Override
    public boolean isUseAdviceWith() {
        return true;
    }

    @Override
    protected RouteBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from("file:/var/file.log&noop=true").routeId("MY_ROUTE").to("direct:processActs");

                from("direct:processActs").process(exchange -> {
                    List<Customer> customers = new ArrayList<>();
                    customers.add(new Customer("F1", "L1"));
                    customers.add(new Customer("F2", "L2"));
                    customers.add(new Customer("F3", "L3"));
                    exchange.getOut().setBody(customers);
                }).to("direct:write2File");

                from("direct:write2File").split(simple("${body}")).log("Content: ${body}");
            }
        };
    }

    @Override
    protected void doPostSetup() throws Exception {
        context.getRouteDefinition("MY_ROUTE").adviceWith(context, new AdviceWithRouteBuilder() {
            @Override
            public void configure() throws Exception {
                replaceFromWith("direct:teststart");
                weaveAddLast().to("mock:end");
            }
        });
        context.start();
    }

    @Test
    public void testUnmarshal() throws Exception {
        mockEndResult.expectedMessageCount(1);

    // ArrayIndex Exception here exchanges list is empty
        Customer resultCustomer = processActs.getExchanges().get(0).getIn().getBody(Customer.class); 
        assertEquals(resultCustomer.toString(),"F1:::L1"); 

        write2File.expectedBodiesReceived("F1:::L1", "F3:::L3", "F2:::L2");
        template.sendBody("direct:teststart", new File("src/test/resources/test.txt"));
        mockEndResult.assertIsSatisfied();

    }

}

【问题讨论】:

  • sendtBody 在您执行断言后被调用。在发送正文之前不会触发路由
  • @NelsonChristos 感谢您的回复,但同样的例外。
  • 您必须在获得交换之前声明模拟。因为这些交换是到达模拟的实际交换。所以它的期望必须首先得到满足,也就是说应该有 1 条消息到达。stackoverflow.com/questions/8579358/…
  • List> list = (List>) mockEndResult.getExchanges().get(0).getIn().getBody();
  • 不,这不起作用,mockend 将只有字符串而不是 POJO 对吗?

标签: java junit apache-camel


【解决方案1】:

看起来您在实际发送任何交换之前正在检查模拟端点。尝试将检查移动到测试的末尾,例如:

@Test
public void testUnmarshal() throws Exception {
    mockEndResult.expectedMessageCount(1);

    write2File.expectedBodiesReceived("F1:::L1", "F3:::L3", "F2:::L2");
    template.sendBody("direct:teststart", new File("src/test/resources/test.txt"));
    mockEndResult.assertIsSatisfied();

    Customer resultCustomer = processActs.getExchanges().get(0).getIn().getBody(Customer.class); 
    assertEquals(resultCustomer.toString(),"F1:::L1"); 
}

更新

仔细观察,我认为你的模拟搞混了。根据您要检查三个客户是否被写出的断言来判断。但是,您的模拟不是为此设置的。

mock:end 被添加到MY_ROUTE 的末尾,但这只会看到处理器在direct:processActs 中返回的整个客户列表

您使用@EndpointInject 声明的模拟也不会参与路由,因为您实际上并未模拟真正的端点。除了mockEndResult,您可以将它们全部删除。

以下测试确实通过了。

@Test
public void testUnmarshal() throws Exception {
    mockEndResult.expectedMessageCount(1);

    template.sendBody("direct:teststart", new File("src/test/resources/test.txt"));

    mockEndResult.assertIsSatisfied();

    @SuppressWarnings("unchecked")
    List<Customer> customers = mockEndResult.getExchanges().get(0).getIn().getBody(List.class);
    assertEquals(customers.get(0).toString(), "F1:::L1");
    assertEquals(customers.get(1).toString(), "F2:::L2");
    assertEquals(customers.get(2).toString(), "F3:::L3");
}

不过,这可能不是您想要测试的。相反,您可以将模拟端点编织到拆分器中,然后您就可以断言单个客户。

@Override
protected void doPostSetup() throws Exception {
    context.getRouteDefinition("MY_ROUTE").adviceWith(context, new AdviceWithRouteBuilder() {
        @Override
        public void configure() throws Exception {
            replaceFromWith("direct:teststart");
        }
    });
    // give direct:write2File the id 'splitter' to be able to advice it
    context.getRouteDefinition("splitter").adviceWith(context, new AdviceWithRouteBuilder() {
        @Override
        public void configure() throws Exception {
            weaveByType(LogDefinition.class).after().to("mock:end");
        }
    });
    context.start();
}

@Test
public void testUnmarshal() throws Exception {
    mockEndResult.expectedMessageCount(3);
    mockEndResult.expectedBodiesReceived("F1:::L1", "F2:::L2", "F3:::L3");

    template.sendBody("direct:teststart", new File("src/test/resources/test.txt"));

    mockEndResult.assertIsSatisfied();
}

【讨论】:

  • 感谢您的回复,但同样的例外。
  • 更新了更多细节并通过了测试
  • 哪个有效,但我不明白你能解释一下吗? +1 谢谢。
猜你喜欢
  • 2012-03-14
  • 2018-06-12
  • 2018-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多