Search code examples
junithamcrest

Hamcrest matchers for a List<Set<String>>


I am trying to write a JUnit test for a method that returns

List<Set<String>> result = build(List<Account> accounts, List<Order> orders);

I can check that I have the expected number of entries with

assertThat(result, hasSize(2));

But I'm struggling to find clear documentation on how to write an assert that the list contains one entry with a set size of 2 and one entry with a set size of 4. If someone could point me to the relevant documentation that I need to read, I would be grateful


Solution

  • I don't recall Hamcrest having anything for this particular setup.

    I would just test one of the sets for size and then ensure the sum is 6

    Using hamcrest-2.2.jar from hamcrest.org and JUnit4 this fails in the 3rd assertThat, since I deliberately created it to fail with an expected value of 5. The test reports no failure when set to 6:

    import static org.hamcrest.Matchers.*;
    import static org.hamcrest.MatcherAssert.assertThat;
    
    import org.junit.Test;
    
    import java.util.List;
    import java.util.Set;
    
    public class MyListTest {
    
      @Test
      public void listSize() {
        MyList tester = new MyList();
        List<Set<String>> result = tester.generate();
    
        // assert statements
        assertThat(result, hasSize(2));                                        // yours
        assertThat(result.get(0), anyOf(hasSize(2), hasSize(4)));              // is either 2 or 4
        assertThat((result.get(0).size() + result.get(1).size()), equalTo(5)); // sum must be 6. FAILS with 5 :)
      }
    }
    

    Tested class:

    import java.util.List;
    import java.util.Set;
    
    public class MyList {
      public List<Set<String>> generate() {
        Set<String> s1 = Set.of("Hello", "World");
        Set<String> s2 = Set.of("Testing", "One", "Two", "Three");
        return List.of(s1,s2);
      }
    }