我有一个场景,我从方法调用收到一个列表,我想断言该列表包含正确的元素。做到这一点的一种方法是在每个元素中查找一些细节,以查看要与哪个预期元素进行比较 - 例如。一个名字。然而,这些元素还包含一个随机生成的 UUID,我不关心比较它。
然后我想一个测试工具可能会拯救我。以下面的简化示例为例。
我有一个班级狗:
public class Dog {
private String name;
private Integer age;
}
它们包含在列表中:
List<Dog> dogs = ... many dogs
现在我想测试列表中是否包含预期的狗,但由于某种原因我不知道某些字段 - 让我们说
age
。
我已经尝试使用assertj和hamcrest,但我找不到正确的解决方案,既比较两个列表,同时又忽略一些字段。
到目前为止,这就是我所拥有的(使用 hamcrest):
List<Dog> actualDogs = codeUndertest.findDogs(new Owner("Basti"));
List<Dog> expectedDogs = createExpectedListOfDogsWithoutTheAge();
Matcher.assertThat(actualDogs.get(0), Matcher.is(com.shazam.shazamcrest.matcher.Matchers
.sameBeanAs(expectedDogs.(0))
.ignoring("age")
))
这可行,但它只比较 Dog 类的两个对象。如何比较两个列表中的所有狗?
额外问题:在不知道顺序的情况下,或者我只需要断言列表中包含预期的狗时,如何比较列表。
尝试一下 AssertJ 的 usingElementComparatorIgnoringFields:
Employee bill = new Employee("Bill", 60, "Micro$oft");
Employee appleBill = new Employee("Billie", 60, "Apple");
List<Employee> employees = newArrayList(bill, appleBill);
Employees[] expectedEmployees = { new Employee("Bill", 60, "Google"),
new Employee("Billie", 60, "Facebook") };
// this assertion succeeds as we don't compare the company field.
assertThat(employees).usingElementComparatorIgnoringFields("company")
.contains(expectedEmployees);
编辑: 可以使用新的递归比较 API,它可以更好地控制比较的内容:https://assertj.github.io/doc/#assertj-core-recursive-comparison-ignoring-fields
上面提到的方法
usingElementComparatorIgnoringFields
现已弃用。您应该使用 usingRecursiveFieldByFieldElementComparatorIgnoringFields
代替它。
例如:
@Test
public void shouldCompareDogsWithoutAge() {
final List<Dog> actual = List.of(new Dog("Azor", null), new Dog("Rex", null));
assertThat(actual)
.usingRecursiveFieldByFieldElementComparatorIgnoringFields("age")
.containsExactlyInAnyOrder(new Dog("Azor", 12), new Dog("Rex", 9));
}
public class Dog {
private String name;
private Integer age;
public Dog(final String name, final Integer age) {
this.name = name;
this.age = age;
}
}
就我而言,我尝试比较不同类别的列表。 @Joel Costigliola 暗示我使用
usingElementComparatorIgnoringFields
,所以我写了这段代码:
List<ClassOne> input = new ArrayList<>();
input.add(...);
...
List<ClassTwo> result = new ArrayList<>();
...
assertThat(result).usingElementComparatorIgnoringFields("field1", "field2").isEqualTo(input);
目前您可以使用
usingRecursiveFieldByFieldElementComparatorIgnoringFields
有配置,因为更新了。
import static org.assertj.core.api.Assertions.*;
public class Dog {
private String name;
private Integer age;
}
@Test
void shouldCompareDogsWithoutAge() {
List<Dog> actual = List.of(new Dog("Azor", 5), new Dog("Rex", 6));
RecursiveComparisonConfiguration configuration =
RecursiveComparisonConfiguration.builder()
.withIgnoredFields("age")
.build();
assertThat(actual)
.usingRecursiveFieldByFieldElementComparatorIgnoringFields(configuration)
.contains(new Dog("Azor", 12));
}