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

使用hamcrest断言不同自定义对象内的值

党权
2023-03-14

我对使用hamcrest进行资产评估还很陌生,而且我已经有一个非常糟糕的案例需要测试。

我们有2个不同的自定义对象的数组列表:FilterItem和MyEnum。两者都包含一个属性——比方说“值”——单元测试要传递的属性应该相等。因为对象是不同的,所以我不能简单地断言它们包含的值,这使得断言更加困难。

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

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()包含()可能是解决方案的一部分?

有什么建议吗?

PS。当前测试没有断言列表的顺序是否相同,但这是我想创建的下一个单元测试。如果有人能给出一个很好的解决方案(不使用所有的for循环),我真的很感激!

共有2个答案

沈茂
2023-03-14

您可以使用hamcrest包含方法来接受匹配器列表。您创建了一个匹配器列表,该匹配器来自预期的ENums,它是列表中的每个项目,一个具有列表中枚举的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的getter,它就可以工作。

卜阳
2023-03-14

您可以事先映射实际和预期的列表,然后使用包含

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));
}

这也表明订单是相同的。我使用新的java-8流api进行映射。

 类似资料:
  • 有没有Hamcrest可以让我明确断言,返回对象的的方法的结果至少有一个对象包含具有特定值的属性? 例如: 测试下的方法返回一个的集合。我需要断言至少有一个人叫彼得。

  • 我试图在spock或hamcrest中编写一个与域相关的自定义断言/匹配器,但我不确定如何继续。 我曾尝试在hamcrest编写一个自定义匹配器,但到目前为止,这只导致我找到了部分解决方案。 我正在寻找一些指导,关于在这种情况下正确的路线是什么。 域对象: ResultMap有一个对象Map 在我的spock测试中,我想做的事情是: 然后,内部代码将评估每个条目,并对内部对象进行适当的测试。 到目

  • 我可以很容易地用两种可能的结果进行断言: 但是,我需要执行断言,我的结果之一等于一些值: 上述方法有效,但是错误消息没有说明哪个结果是。Hamcrest有类似以下的吗?

  • 我试图创建一个音频捕获活动,所以我从android文档中复制了这个类,如下所示 在我的xml页面中,我试图创建一个id为麦克风的RecordButton。类似这样的东西 现在,当我尝试运行该应用程序时,会出现以下输出

  • 其中 actual 是 ID 为 Long 的 POJO。 我明白了, 方法 assertThat(T, Matcher 从各种文档和其他stackoverflow页面来看,它应该是有效的,但我得到了上述错误。

  • 我一直在Eclipse中使用JUnit创建单元测试,我很清楚JUnit的基本原理。测试按应有的方式运行,现在是时候找到一种报告失败测试的好方法了。我在web上遇到的大多数例子都是使用某种构建的系统,如Ant、Maven或Hudson,在构建项目的同时运行测试,但在构建过程中不需要这种集成。测试应该能够独立于构建系统运行。最后,这些系统只需从JUnit获取信息,并将其放入一个漂亮的HTML布局中。