当前位置: 首页 > 知识库问答 >
问题:

Hamcrest集合匹配列表中的对象具有与另一个列表中的值匹配的字段

邓翼
2023-03-14

我有一个正在测试的方法,它返回一个对象列表。。。例如“Person”对象。

我有一个“预期的最后名字”列表来验证结果。

我目前有一个工作测试,它html" target="_blank">循环遍历“expectedLastNames”中的名称,并断言每个名称都包含在“Person”对象列表中。与此类似(请注意,以下代码段位于Kotlin中):

expectedLastNames.forEach { expectedLastName ->
    assertThat(listOfPeople, hasItem(hasProperty("lastName", `is`(expectedLastName.trim()))))
}

当断言通过时,这非常有效,并验证了我的方法。然而,当测试失败时,这是非常麻烦的,因为一旦遇到缺少的名称并且没有断言其余名称,它就会快速失败。我更愿意改进我的断言,一次报告所有丢失的名字,而不是一次一个。

大致如下:

assertThat(expectedLastNames, allItems(lastNameMatches(listOfPeople)));

我希望我的断言失败消息类似于:

应为匹配所有“Smith,Jones,Davis”的列表,但在“Person[firstName=John,lastName=“Jones”]、Person[firstName=Sarah,lastName=Jones]中未找到[“Smith”,“Davis”]

如果结果中有其他具有lastName值的Person对象未包含在“expectedLastNames”中,则只要结果中表示了“expectedLastNames”中的所有名称,此操作仍应通过。

同样重要的是要知道这是一个Junit5参数化测试,“expectedLastNames”是传入的参数之一。因此,我不能将姓氏硬编码到断言中。

是否有一个汉克雷斯特收集匹配,将做我想要的?或者,如果没有,谁能让我从一个定制匹配器开始呢?

感谢您的帮助。

共有1个答案

长孙鸿振
2023-03-14

您可以使用Iterable提供的hamcrest匹配器来完成此操作:

import org.junit.Test;

import java.util.List;

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;

public class MatchValuesInAnotherListTest {
    static class Person{
        private final String firstName;
        private final String lastName;

        Person(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }

        public String getFirstName() {
            return firstName;
        }

        public String getLastName() {
            return lastName;
        }
    }

    @Test
    public void matchLastNames() {
        List<Person> listOfPeople = asList(new Person("Paul", "Smith"), new Person("John", "Davis"));

        assertThat(listOfPeople.stream().map(Person::getLastName).collect(toList()), containsInAnyOrder("Davis", "Smith"));
        assertThat(listOfPeople.stream().map(Person::getLastName).collect(toList()), contains("Smith", "Davis"));
    }
}

它们将提供格式良好的故障消息:

java.lang.AssertionError: 
Expected: iterable over ["Smith"] in any order
     but: Not matched: "Davis"

    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
 类似资料:
  • 我有一个数字列表L。还有另一个数字列表M。我需要返回一个在L和M中找到的数字列表L。 编辑:从数学上讲,我正在寻找多集交点。 例子: L=3,,4,,5,,,6 M=,7,,,,1 L'=9,1,2,1 我为此编写了以下代码: 虽然它达到了目的,但我想知道是否有一种惯用的Perl6方法可以做到这一点? 一些背景:我一直在尝试一起学习Perl6和Python,并用这两种语言解决相同的难题。Pytho

  • 问题内容: 我有一个列表,数组或您熟悉的任何一种语言。例如,names:如果与这些名称之一匹配,我想查询该字段。 一种方法是使用OR过滤器。例如 有什么更好的办法吗?如果它是查询,则比过滤器更好。 问题答案: 哪一个Elasticsearch会像您曾经使用过的那样重写 在大多数情况下,使用布尔型过滤器时,使用过滤器比或更好。原因在Elasticsearch博客中进行了解释:http://www.e

  • 嗨,我有两个对象列表。清单1和清单2 App1中的员工列表 在sql中,我们可以很容易地通过ID列进行连接。但是这里要点击seperate API来阅读清单2。 我可以从清单2创建map,并将EmpId作为键,继续从map获取对象,并将详细信息设置到清单1。 想知道有没有更好的方法来做这件事。

  • 很抱歉标题太长,但我的问题如下; 我有这些课程; 和 和 如果只有断言它拥有的列表,我会使用以下自定义匹配器;

  • 问题内容: 我正在使用MySQL。我有一个名为EMP的表,现在我需要再创建一个具有相同架构,相同列和相同约束的表(EMP_TWO)。我怎样才能做到这一点? 问题答案: 要基于其他表结构/约束创建新表,请使用: 要跨多个数据复制,请使用 创建表格文档 当心关于LIKE选项的注意事项: 使用LIKE根据另一个表的定义(包括原始表中定义的任何列属性和索引)创建一个空表: CREATE TABLE new

  • 我试图使用org.hamcrest.matchers.contains(java.util.list >),但是编译器告诉我它无法解析该方法。 我甚至尝试了Hamcrest在这里给出的示例,但得到了相同的编译错误: 但随后我得到了另一个编译错误: 有没有办法恰当地使用这种方法?