Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check for size AND presence of some items in collections in hamcrest

I'm using Hamcrest 1.3 and trying to achieve the following in a more compact way.

Consider following test case:

@Test
public void testCase() throws Exception {

    Collection<String> strings = Arrays.asList(
        "string one",
        "string two",
        "string three"
    );

    // variant 1:
    assertThat(strings, hasSize(greaterThan(2)));
    assertThat(strings, hasItem(is("string two")));

    // variant 2:
    assertThat(strings, allOf(
        hasSize(greaterThan(2)),
        hasItem(is("string two"))
    ));
}

the goal here is to check for both size of collection AND some specific items to be included.

Where first variation is possible and accepted, it is not always that easy to do it, because maybe the collection is itself a result of some other operations and therefore it makes more sense to do all the operations on it using an allOf operation. Which is done in second variation above.

However containing the code of second variation will result in following compile time error:

error: no suitable method found for allOf(Matcher<Collection<? extends Object>>,Matcher<Iterable<? extends String>>)

Is there actually any specific way of testing for size AND items of a collection in Hamcrest using a single shot operation (like allOf)?

like image 338
mohamnag Avatar asked Oct 21 '16 12:10

mohamnag


People also ask

Which matchers method is used to test the size of a list in a test condition in JUnit?

java - jUnit testing using hamcrest matcher - how to test the size of a collection.

What is a matcher in Hamcrest?

Hamcrest is a framework for writing matcher objects allowing 'match' rules to be defined declaratively. There are a number of situations where matchers are invaluable, such as UI validation or data filtering, but it is in the area of writing flexible tests that matchers are most commonly used.

What is the Hamcrest matcher to test if a string contains another string?

Class StringContains. Tests if the argument is a string that contains a substring. Creates a matcher that matches if the examined String contains the specified String anywhere.


Video Answer


2 Answers

I think the compiler is not able to sort out the generics. The following is working for me (JDK 8u102):

assertThat(strings, Matchers.<Collection<String>> allOf(
    hasSize(greaterThan(2)),
    hasItem(is("string two"))
));
like image 143
eee Avatar answered Oct 11 '22 03:10

eee


I know this question is old but I still want to answer it in case someone needs explanation.

If you want to use allOf(...) just make sure nested matchers return types match. In your test case hasSize returns org.hamcrest.Matcher<java.util.Collection<? extends T>> but hasItem yields org.hamcrest.Matcher<java.lang.Iterable<? super T>>. In this case I'd recommend to use iterableWithSize(int size) where return type is Matcher<java.lang.Iterable<T>>, so you could do:

assertThat(strings, allOf( iterableWithSize(greaterThan(2)), hasItem("string two") ) );

like image 4
fywe Avatar answered Oct 11 '22 04:10

fywe