Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
src Fix possible NPE in Wrapper.equals Sep 29, 2015

Collection Matchers


Matches only if collection has unique elements

public void assertionShouldNotBeThrownWhenThereAreNoDuplicates() {
    List<String> collectionWithDuplicates = asList("veni", "vidi", "vici");
    assertThat(collectionWithDuplicates, containsUniqueItems());


What if we want to compare two lists. But we also want to know all the difference between them. HasSameItemsAsListMatcher helps with it:

@Test(expected = AssertionError.class)
public void listNotEqualSortedAndNotContainsSomeItems() throws Exception {
    List<String> actual = asList("1", "2", "3");
    List<String> expected = asList("3", "2", "1", "4");

    assertThat(actual, hasSameItemsAsList(expected));

It prints:

Expected: Lists contains same items
(In Expected but not in Actual) [<1>]:
-> <4>

Also we can check the sorting order with help of mode .sameSorted()

public void listNotSameOrderButEqual() throws Exception {
    List<String> actual = asList("1", "2", "3");
    List<String> expected = asList("3", "2", "1");

    assertThat(actual, hasSameItemsAsList(expected).sameSorted());

It prints

Expected: Lists contains same items and sorted equally
(Not sorted correctly) [<2>]:
-> "Expected 3 on position [0], but was - 1"
-> "Expected 1 on position [2], but was - 3"


This matcher is same as matcher for list, but can't compare sorting order because of use jdk collections classes It prints:

Expected: collections contains same items
(Not equal frequency) [<2>]:
-> "3 - expected [2] times, but frequency was - [1]"
-> "2 - expected [2] times, but frequency was - [1]"

Extended usage of HasSameItemsAsListMatcher

We can define new output of every element that don't matches in case of failure. Also we can override the equality method with help of this matcher

  • First, we need to override equals behaviour. For example we want to compare two lists with non case sensitive matching:
List<String> actual = asList("aBc", "DEf", "gHi");
List<String> expected = asList("Abc", "DeF", "gHI");
  • Extend abstract class Wrapper<String> - don't forget to use generic String as we compare strings. Now we should override 2 methods - safelyEquals and asString
public class IgnoreCaseStringWrapper extends Wrapper<String> {
    public boolean safelyEquals(String actual, String expected) {
        return actual.toLowerCase().equals(expected.toLowerCase());

    public String asString(String obj) {
        return obj;

Parent abstract class already check for null all elements before pass it to child methods

  • Next, implement interface of wrapper factory - for that override only one method: Wrapper<String> newWrapper()
public class IgnoreCaseWrapperFactory implements WrapperFactory<String> {
   public Wrapper<String> newWrapper() {
        return new IgnoreCaseStringWrapper();
  • Then, pass factory object to be used for producing new wrappers
public void useCustomWrapper() throws Exception {
   assertThat(actual, hasSameItemsAsList(expected).useWrapperFactory(new IgnoreCaseWrapperFactory()));