使用hamcrest比较包含另一个对象列表的对象列表

时间:2016-10-05 15:51:33

标签: java junit hamcrest

我有以下对象图:

Order --> List of Lines --> List of Shipments object

Line 对象有一个名为 lineNumber 的属性。 Shipment 对象还有一个名为 lineNumber 的属性。我不知道为什么他们两个都有,但那些是我处理过的卡片。

是否可以比较每一行的line.getLineNumber().equals(shipment.getLineNumber())

所以实际上,我想测试以下内容:

for(Line line : order.getLines(){
    for(Shipment ship : line.getShipments()) {
         assertEquals(line.getLineNumber(), shipment.getLineNumber());
    }
}

我尝试了以下操作,但它不起作用:

assertThat(order.getLines(), everyItem(Matchers.<Line>hasProperty("shipments", everyItem(Matchers.<Shipment>hasProperty("lineNumber", is(line.getLineNumber())))))

显然,我没有对行的引用,那么如何比较这种情况下的值呢?

2 个答案:

答案 0 :(得分:0)

断言正好接受两个参数(好吧,三个,但第三个只是要打印的消息失败):

  1. 实际值(所以,是的,getLines())就可以了
  2. 预期值,应该是某种形式的匹配器
  3. 因此,您将多个“预期匹配器”添加到相同调用的想法根本不起作用。

    你得到了:

    assertThat(a1, e1, e2, e3);
    

    相反:将你的单个调用与assertThat分成几个 - 一个用于你想要检查的每个“预期”条件。

    assertThat(a1, e1;
    assertThat(a1, e2);...
    

    如果上述方法无效,或者您希望编写的代码只需要一个assertThat,那么您可以随时前进并编写自己的客户匹配器,例如从我为其他人编写的简单解决方案开始question

    记录:这是我的第一个自定义匹配器,我在不到10分钟的时间内完成了工作;换句话说:一旦你进入概念,这是一个非常简单的任务!

答案 1 :(得分:0)

不完全是你想要的,但至少适合一行:

    order.getLines().forEach(
        l -> 
          assertThat(l.getShipments(), 
             everyItem(
                  hasProperty("lineNumber", is(l.getLineNumber())))));

正如你所说,让匹配器保持对被检查对象的引用可能会很棒,但我不知道如何使用Hamcrest。