【问题标题】:Assert that one of string in array contains substring断言数组中的字符串之一包含子字符串
【发布时间】:2017-01-24 12:24:11
【问题描述】:
List<String> expectedStrings = Arrays.asList("link1", "link2");
List<String> strings = Arrays.asList("lalala link1 lalalla", "lalalal link2 lalalla");

对于每个预期字符串,我需要断言“字符串”中的任何字符串都包含预期字符串。 我如何用 Hamcrest 断言这一点? 感谢您的关注。

【问题讨论】:

  • 您需要告诉我们您的尝试。

标签: java hamcrest


【解决方案1】:

更新

在检查了这个旧答案后,我发现您可以使用更好的内置匹配器组合,使断言和错误消息更具可读性:

expectedStrings.forEach(expectedString -> 
    assertThat(strings, hasItem(containsString(expectedString))));

原答案供参考

你可以用流很容易地做到这一点:

assertThat(expectedStrings.stream().allMatch(
    expectedString -> strings.stream()
                             .anyMatch(string -> string.contains(expectedString))),
    is(true));

allMatch 将确保检查所有expectedStrings,并且在strings 上使用anyMatch 您可以有效地检查任何字符串是否包含预期的字符串。

【讨论】:

  • 这很好。我现在意识到我做了一个错误的推论,我的答案是错误的。干得好。
【解决方案2】:

目前在 hamcrest 中没有任何匹配器具有此要求,尽管您可以组合多个,但这是不可能的。

所以,在我看来,在像您这样的情况下,最好的解决方案是创建自己的匹配器为什么?

  • 可以重复使用
  • 可维护
  • 更具可读性

所以在你的情况下,你需要匹配第一个列表包含第二个的任何字符串,你可以像下一个一样创建一个匹配器:

public class ContainsStringsOf extends BaseMatcher<List<String>> {

    private final List<String> valuesToCompare;

    public ContainsStringsOf(List<String> valuesToCompare) {
        this.valuesToCompare = valuesToCompare;
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("doesn't contains all of " + valuesToCompare.toString() + " text");
    }

    @Override
    public boolean matches(Object o) {
        List<String> values = (List<String>) o;
        for (String valueToCompare : valuesToCompare) {
            boolean containsText = false;
            for (String value : values) {
                if (value.contains(valueToCompare)) {
                    containsText = true;
                }
            }
            if (!containsText) {
                return false;
            }
        }
        return true;
       //note: you can replace this impl with java-8 @florian answer comparison
       //return valuesToCompare.stream().allMatch(exp -> strings.stream().anyMatch(st-> st.contains(exp)))
    }

    @Factory
    public static Matcher<List<String>> containsStringsOf(List<String> collection) {
        return new ContainsStringsOf(collection);
    }
}

那么你就可以像使用hamcrest matcher一样使用它了:

List<String> expectedStrings = Arrays.asList("link1", "link2");
List<String> strings = Arrays.asList("lalala link1 lalalla", "lalalal link2 lalalla");
Assert.assertThat(strings , containsStringsOf(expectedStrings));

【讨论】:

    猜你喜欢
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 2019-11-12
    • 2019-03-15
    • 2022-05-27
    • 2017-10-15
    • 2022-01-13
    • 1970-01-01
    相关资源
    最近更新 更多