【问题标题】:Use Hamcrest to check if some elements are in a Collection使用 Hamcrest 检查某些元素是否在集合中
【发布时间】:2019-07-12 17:14:56
【问题描述】:

我正在尝试测试我希望集合具有三个特定值中的两个的代码。有没有一种简洁的方法可以用 Hamcrest 1.3 进行测试?

我想要这样的东西:

Collection<String> set = new HashSet<>();
set.add("A");
set.add("B");
set.add("C");
// Remove an indeterminate element
set.iterator().next().remove();

// What the matcher actually is is the question
assertThat(set, hasSomeOf("A", "B", "C")); 
assertThat(set, hasSize(2));

只要set 包含三个值中的两个,代码就可以正常工作,而缺少哪个实际上取决于实际示例中的String 哈希码。

我认为这可能是最好的处理方式:

Collection<String> expected = Arrays.asList("A", "B", "C");
for (String value: set) {
  assertThat(value, isIn(expected));
  expected.remove(value);
}

这也有一个缺点,即我不能使用额外的匹配器,我希望在我的真实案例中使用它。 (为了重用我虚构的匹配器,我想做类似hasSome(startsWith("A"), startsWith("B"), startsWith("C"))

澄清

如果set 包含hasSomeOf 的参数中没有的内容,则匹配器失败。

【问题讨论】:

  • 您不想创建类似hasSome(Matcher&lt;Integer&gt; countMatcher, Matcher&lt;?&gt;... matchers) 的东西,然后像hasSome(equals(2), hasItem("A"), hasItem("B"), hasItem("C")) 一样被调用吗?我也将第一个参数保留为匹配器,因为它也允许您拥有比细节更少/更多的参数。
  • 如果set = { "C", "H" } 怎么办?检查hasSomeOf("A", "B", "C") 为真,检查hasSize(2) 为真,但不能保证集合“具有三个特定值中的两个”。
  • 我的隐含语义(可能更清楚)是 ["C", "H"] 会失败 hasSome("A", "B", "C")

标签: java hamcrest


【解决方案1】:

我相信您正在寻找的匹配器是 everyItem()oneOf()anyOf() 的组合。对于hasSome("A", "B", "C"),场景["C", "H"] 应该失败,可以写成如下:

assertThat(set, everyItem(is(oneOf("A", "B", "C"))));

并且在添加项目H时会导致以下失败:

Expected: every item is is one of {"A", "B", "C"}
     but: an item was "H"

对于您希望包含多个匹配器的其他场景,您可以简单地替换期望。

assertThat(set, everyItem(is(anyOf(startsWith("A"), startsWith("B"), startsWith("C")))));

这将导致:

Expected: every item is is (a string starting with "A" or a string starting with "B" or a string starting with "C")
     but: an item was "H"

【讨论】:

  • 感谢您的回复,它应该被标记并且是正确的。一件小事:我不得不使用isOneOf 而不是is(oneOf(..,因为我只发现isOneOforg.hamcrest.Matchers 中可用hamcrest-library-1.3.0
猜你喜欢
  • 1970-01-01
  • 2017-02-05
  • 1970-01-01
  • 1970-01-01
  • 2021-05-05
  • 2010-11-23
  • 2021-12-22
  • 2014-11-14
  • 1970-01-01
相关资源
最近更新 更多