繁体   English   中英

使用Hamcrest在不同的自定义对象中声明值

[英]Asserting values inside different custom objects using hamcrest

对于使用hamcrest进行断言,我是一个新手,而且我已经有一个非常讨厌的案例可以测试。

我们有2个不同的自定义对象的数组列表:FilterItem和MyEnum。 两者都包含一个属性-假设是“值”-要通过单元测试,该属性应该相等。 因为对象是不同的,所以我不能简单地assertThat (filterItems, hasItems(expectedEnums)) ,所以我想断言它们包含的值,这使它更加困难。

在每个我想断言的单元测试中,我将assert-logic提取到一个新方法中,如下所示:

private void assertIfFilterItemValuesAreEqualToExpectedEnumValues(ArrayList<FilterItem> filterItems, ArrayList<MyEnum> expectedEnums)
{
   ArrayList<String> filterItemValues = getFilterItemValues(filterItems);

   assertEquals(expectedEnums.size(), filterItemValues.size());
   // This assert prevents unittests to pass unfairly, in case the array is empty
   assertFalse("No expectedEnums to assert!", expectedEnums.isEmpty());

   for (MyEnum myEnum : expectedEnums)
   {
      String myEnumValue = myEnum.getValue();
      assertThat(filterItemValues, hasItem(myEnumValue));
   }
 }

private ArrayList<String> getFilterItemValues(ArrayList<FilterItem> filterItems)
{
   ArrayList<String> filterItemValues = new ArrayList<>();
   for (FilterWaardeItem filterItem : filterItems)
   {
      filterItemValues.add(filterItem.value);
   }
   return filterItemValues;
}

单元测试现在全部通过了,所以我猜实现是正确的,但是我感觉实现可能更简单。 我的感觉是,至少可以省略枚举的for循环。 此外,如果该解决方案也可以使for循环之前的2个断言也不必要,那就太好了! 可能hasProperty()contains()可能是解决方案的一部分?

有什么建议吗?

ps。 当前的测试无法断言列表的顺序是否相同,但这是我要创建的下一个单元测试。 如果有人能为该解决方案提供一个不错的解决方案(不使用所有for循环),我将不胜感激!

您可以预先映射实际列表和期望列表,然后使用contains

private void assertIfFilterItemValuesAreEqualToExpectedEnumValues(ArrayList<FilterItem> filterItems, ArrayList<MyEnum> expectedEnums) {
    List<String> actual = filterItems.stream()
            .map(item -> item.value)
            .collect(toList());
    String[] expected = expectedEnums.stream()
            .map(myEnum -> myEnum.getValue())
            .toArray(String[]::new);

    assertThat(actual, contains(expected));
}

这也断言顺序是相同的。 我使用了新的流api进行映射。

您可以使用hamcrest contains方法来接受匹配器列表。 您可以从hasProperty创建匹配器列表, expectedEnums是列表中的每个项目,并且具有hasProperty匹配器以及列表中的枚举。

    final List<Matcher<? super Object>> enumListMatcher = expectedEnums.stream()
            .map(myEnum -> hasProperty("value", is(myEnum.getValue()))).collect(Collectors.toList());
    assertThat(filterItems, contains(enumListMatcher));

注意 :只要您在FilterItem具有value ,它就可以工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM