Hamcrest中相反的含义是什么?

21

包含的相反是什么?

    List<String> list = Arrays.asList("b", "a", "c");
    // should fail, because "d" is not in the list

    expectedInList = new String[]{"a","b", "c", "d"};
    Assert.assertThat(list, Matchers.contains(expectedInList));


    // should fail, because a IS in the list
    shouldNotBeInList = Arrays.asList("a","e", "f", "d");
    Assert.assertThat(list, _does_not_contains_any_of_(shouldNotBeInList)));

应该包含哪些内容,_does_not_contains_any_of_ 代表什么?


你能否仅仅取反 contains 方法?例如 !contains(shouldNotBeInList)。我还没有做过这样的操作,所以不确定是否可行,但值得一试。 - Hypnic Jerk
2
@Michael Pickett:not(contains all elements) = contains not all elements - pihentagy
你正在使用Hamcrest吗?如果是这样,语法应该更像!anyOf(...)。我认为,只是看API,因为我从未使用过Hamcrest。 - Robert Benson
5个回答

28

你可以如下方式组合三个内置的匹配器:

import static org.hamcrest.Matchers.everyItem;
import static org.hamcrest.Matchers.isIn;
import static org.hamcrest.Matchers.not;

@Test
public void hamcrestTest() throws Exception {
    List<String> list = Arrays.asList("b", "a", "c");
    List<String> shouldNotBeInList = Arrays.asList("a", "e", "f", "d");
    Assert.assertThat(list, everyItem(not(isIn(shouldNotBeInList))));
}

执行此测试将会得到:

期望值:每个项都不是{"a", "e", "f", "d"}之一
但实际上:有一项是"a"


感谢您的回答。现在我有一个关于匹配器严格程度的相关问题:http://stackoverflow.com/questions/40015862/strict-matching-in-hamcrest - pihentagy
1
嗯,针对检查子字符串是否不包含,有什么解决方法呢? - fabb
2
hasItems()方法之后,这非常令人费解。我尝试使用not(hasItems())已经有一段时间了,但并没有成功。感谢您的回答。 - Oleg Kuts

4
尝试这种方法:

请尝试以下方法:

public <T> Matcher<Iterable<? super T>> doesNotContainAnyOf(T... elements)
{
    Matcher<Iterable<? super T>> matcher = null;
    for(T e : elements)
    {
        matcher = matcher == null ?
            Matchers.not(Matchers.hasItem(e)) :
            Matchers.allOf(matcher, Matchers.not(Matchers.hasItem(e)));
    }
    return matcher;
}

有了这个测试用例:

List<String> list = Arrays.asList("a", "b", "c");
// True
MatcherAssert.assertThat(list, doesNotContainAnyOf("z","e", "f", "d"));
// False
MatcherAssert.assertThat(list, doesNotContainAnyOf("a","e", "f", "d"));

2
JavaDoc上,我可以看到一种笨拙的方法来实现。可能有更好的方法!此代码测试列表不包含a和不包含b等...
List<Matcher> individual_matchers = new ArrayList<Matcher>();
for( String s : shouldNotBeInList ) {
    individual_matchers.add(Matchers.not(Matchers.contains(s)); // might need to use Matchers.contains({s}) - not sure
}
Matcher none_we_do_not_want = Matchers.allOf(individual_matchers);
Assert.assertThat(list, none_we_do_not_want);

(未经测试,可能有错误:/ 希望能有所帮助)

1
我曾经遇到过同样的问题。我的解决方案只是将这个匹配的逻辑反转了一下。
以下是代码片段:
this.mockMvc.perform(get("/posts?page=0&size=1")
                .with(httpBasic(magelan.getUserName(), magelan.getPassword()))
                .accept(MediaType.parseMediaType("text/html;charset=UTF-8")))
                .andExpect(status().isOk())
                .andExpect(content().contentType("text/html;charset=UTF-8"))
                .andExpect(content().string(allOf(
                        containsString("First post")
                )))
                .andExpect(content().string(allOf(
                        not(containsString("Second post"))
                )));

0
作为一种解决方法,可以使用以下内容:
列表 - shouldNotBeInList 应该等于列表本身(需要转换为集合)
    Set<String> strings = new HashSet<>(list);
    strings.removeAll(shouldNotBeInList);

    Set<String> asSet = new HashSet<>(list);
    Assert.assertTrue(strings.equals(asSet));

但是应该有更好的方法,我希望如此。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接