【问题标题】:Asserting values inside different custom objects using hamcrest使用 hamcrest 在不同的自定义对象中断言值
【发布时间】:2016-04-19 09:09:17
【问题描述】:

我对使用 hamcrest 进行断言还是很陌生,而且我已经有一个非常糟糕的案例要测试。

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

在我想要断言的每个单元测试中,我已将断言逻辑提取到一个新方法中,如下所示:

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 循环),我将不胜感激!

【问题讨论】:

    标签: java unit-testing hamcrest


    【解决方案1】:

    您可以事先映射实际和预期列表,然后使用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 进行映射。

    【讨论】:

      【解决方案2】:

      您可以使用接受匹配器列表的 hamcrest contains 方法。 您从 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 的吸气剂,它就可以工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-07-09
        • 2018-02-03
        • 1970-01-01
        • 1970-01-01
        • 2014-08-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多