Centurion, South Africa info@code2bits.com On Request

Writing Assertions for Collections using Hamcrest and JUnit

In this post, I will show you how to write assertions for Collections making use of the Hamcrest library when writing your JUnit testcases. The post provides some useful examples, and some important tips I’ve learned through experience.

Requirements

The following list defines the technologies and libraries I used to implement the sample code:

Multiple Posts

This will form part of a multi-part series on how to write assertions using Hamcrest and JUnit.

Introduction

Hamcrest is a framework that assists the writing of unit testcases in the Java programming language. The name Hamcrest is an anagram for “matchers”. Hamcrest is a library of matchers, which can be combined to create flexible expressions of intent in tests, thus allowing ‘match’ rules to be defined declaratively. These matchers have uses in unit testing frameworks such as JUnit and jMock. Hamcrest has been included in JUnit 4 since 2012, but was omitted from Junit 5 in 2017.

Even though the assertion facilities provided by JUnit Jupiter are sufficient for many testing scenarios, there are times when more power and additional functionality such as matchers are desired or required. In such cases, the JUnit team recommends the use of third-party assertion libraries such as AssertJ, Hamcrest, Truth, etc. Developers are therefore free to use the assertion library of their choice. ~ JUnit 5 User Guide

Examples: Assertions for Collections

This section contains a number of examples of how to make use of the Hamcrest Java Library to write assertions for Collections as part of JUnit test cases. This is not suppose to be a complete list of all possible scenarios in which you can write assertions for Collections, but serves as a list of frequently used examples.

download code


1. Assert that two Collections are equal

A JUnit test method with an assertion that matches when two collections are of the same length and contain items that are equal to each other.

@Test
public final void validateTwoCollectionsEqual() {
    List<String> expectedResult = Arrays.asList("ABC", "DEF", "GHI");
    List<String> actualResult = Arrays.asList("ABC", "DEF", "GHI");
   
    assertThat(actualResult, is(expectedResult));
    assertThat(actualResult, equalTo(expectedResult));
    assertThat(actualResult, is(equalTo(expectedResult)));
}

2. Assert that two Collections are not equal

A JUnit test method with an assertion that matches when two collections are not of the same length or contain items that are not equal to each other.

@Test
public final void validateTwoCollectionsNotEqual() {
    List<String> expectedResult = Arrays.asList("ABC", "DEF", "GHI");
    List<String> actualResult = Arrays.asList("AAA", "BBB", "CCC");
   
    assertThat(actualResult, is(not(expectedResult)));
}

3. Assert that a Collection is null

A JUnit test method with an assertion that matches when the Array is null.

@Test
public final void validateCollectionNullValue() {
    List<String> actualResult = null;
   
    assertThat(actualResult, is(nullValue()));
}

4. Assert that a Collection is not null

A JUnit test method with an assertion that matches when the Array is not null.

@Test
public final void validateCollectionNotNullValue() {
    List<String> actualResult = Arrays.asList("ABC", "DEF", "GHI");
   
    assertThat(actualResult, is(notNullValue()));
}

5. Assert that a Collection is empty

A JUnit test method with an assertion that matches when the size of the collection is zero.

@Test
public final void validateCollectionIsEmpty() {
    List<String> actualResult = new ArrayList<String>();
        
    assertThat(actualResult, empty());
    assertThat(actualResult, is(empty()));
}

6. Assert that a Collection is specific length or size

A JUnit test method with an assertion that matches when the size of the collection equals the specified size.

@Test
public final void validateCollectionHasSize() {
    List<String> actualResult = Arrays.asList("ABC", "DEF", "GHI");
        
    assertThat(actualResult, hasSize(3));
    assertThat(actualResult, hasSize(equalTo(3)));
}

7. Assert that a Collection contains non-empty items

A JUnit test method with an assertion that matches when every item within the collection is not empty.

@Test
public final void validateEveryItemCollection() {
    List<String> actualResult = Arrays.asList("ABC", "DEF", "GHI");
   
    assertThat(actualResult, everyItem(not(isEmptyString())));
}

8. Assert that a Collection is an instance of type X

A JUnit test method with an assertion that matches when the examined collection is an instance of the specified type.

@Test
public final void validateColelctionInstanceOfType() {
    List<String> actualResult = Arrays.asList("ABC", "DEF", "GHI");

    assertThat(actualResult, isA(List.class));
    assertThat(actualResult, any(List.class));
    assertThat(actualResult, instanceOf(List.class));
}

9. Assert that a Collection contains a set of values

A JUnit test method with an assertion that matches when a single pass over the examined Iterable yields a single item that satisfies the specified matcher.

@Test
public final void validateCollectionContains() {
    List<String> actualResult = Arrays.asList("ABC", "DEF", "GHI");
        
    assertThat(actualResult, contains("ABC", "DEF", "GHI"));
    assertThat(actualResult, contains(equalTo("ABC"), equalTo("DEF"), equalTo("GHI")));
    assertThat(actualResult, contains(Arrays.asList(equalTo("ABC"), equalTo("DEF"), equalTo("GHI"))));
}

10. Assert that a Collection contains a set of values in any order

A JUnit test method with an assertion that matches when a single pass over the examined Iterable yields a series of items, each satisfying one matcher anywhere in the specified collection of matchers.

@Test
public final void validateCollectionContainsInAnyOrder() {
    List<String> actualResult = Arrays.asList("ABC", "DEF", "GHI");
        
    assertThat(actualResult, containsInAnyOrder("GHI", "ABC", "DEF"));
    assertThat(actualResult, containsInAnyOrder(equalTo("GHI"), equalTo("ABC"), equalTo("DEF")));
    assertThat(actualResult, containsInAnyOrder(Arrays.asList(equalTo("GHI"), equalTo("ABC"), equalTo("DEF"))));
}

11. Assert that a Collection has a single item

A JUnit test method with an assertion that matches when a single pass over the examined Iterable yields at least one item that is equal to the specified item.

@Test
public final void validateCollectionHasItem() {
    List<String> actualResult = Arrays.asList("ABC", "DEF", "GHI");
    String expectedValue = "DEF";
        
    assertThat(actualResult, hasItem(expectedValue));
}

12. Assert that a Collection has a multiple items

A JUnit test method with an assertion that matches when a single pass over the examined Iterable yields multiple items that are equal to the set of items.

@Test
public final void validateCollectionHasItems() {
    List<String> actualResult = Arrays.asList("ABC", "DEF", "GHI");
    String expectedValue1 = "ABC";        
    String expectedValue2 = "DEF";
        
    assertThat(actualResult, hasItems(expectedValue1, expectedValue2));
    assertThat(actualResult, hasItems(equalTo(expectedValue1), equalTo(expectedValue2)));
}

13. Assert that a Collection has an entry

A JUnit test method with an assertion that matches when the examined Map contains at least one entry whose key satisfies the specified keyMatcher and whose value satisfies the specified valueMatcher.

@Test
public final void validateCollectionHasEntry() {
    Map<String, String> actualResult = new HashMap<String, String>();
    actualResult.put("1", "ABC");
    actualResult.put("2", "DEF");
    actualResult.put("3", "GHI");
        
    assertThat(actualResult, hasEntry("1", "ABC"));
    assertThat(actualResult, hasEntry(equalTo("1"), equalTo("ABC")));
}

14. Assert that a Collection has a specific key

A JUnit test method with an assertion that matches when the examined Map contains at least one key that satisfies the specified matcher.

@Test
public final void validateCollectionHasKey() {
    Map<String, String> actualResult = new HashMap<String, String>();
    actualResult.put("1", "ABC");
    actualResult.put("2", "DEF");
    actualResult.put("3", "GHI");
        
    assertThat(actualResult, hasKey("1"));
    assertThat(actualResult, hasKey(equalTo("1")));
}

15. Assert that a Collection has a specific value

A JUnit test method with an assertion that matches when the examined Map contains at least one value that is equal to the specified value.

@Test
public final void validateCollectionHasValue() {
    Map<String, String> actualResult = new HashMap<String, String>();
    actualResult.put("1", "ABC");
    actualResult.put("2", "DEF");
    actualResult.put("3", "GHI");
        
    assertThat(actualResult, hasValue("ABC"));
    assertThat(actualResult, hasValue(equalTo("ABC")));
}

16. Assert that a Collection is empty

A JUnit test method with an assertion that matches when a collection’s isEmpty method returns true.

@Test
public final void validateCollectionIsEmptyColelctionOfType() {
    List<String> actualResult = new ArrayList<String>();
        
    assertThat(actualResult, emptyCollectionOf(String.class));
    assertThat(actualResult, is(emptyCollectionOf(String.class)));
}

16. Assert that a Iterable is empty

A JUnit test method with an assertion that matches when a iterable has no items.

@Test
public final void validateCollectionIsEmptyIterableOfType() {
    List<String> actualResult = new ArrayList<String>();
        
    assertThat(actualResult, emptyIterableOf(String.class));
    assertThat(actualResult, is(emptyIterableOf(String.class)));
}

17. Combining Matchers using Both

A JUnit test method with an assertion that matches when both of the specified matchers match the examined object.

@Test
public final void validateBothCollectionValues() {
    List<String> actualResult = Arrays.asList("ABC", "DEF", "GHI");
    String expectedResult1 = "A";
    String expectedResult2 = "C";
        
    assertThat(actualResult.get(0), both(startsWith(expectedResult1)).and(endsWith(expectedResult2)));
}

18. Combining Matchers using Either

A JUnit test method with an assertion that matches when either of the specified matchers match the examined object.

@Test
public final void validateEitherCollectionValues() {
    List<String> actualResult = Arrays.asList("ABC", "DEF", "GHI");
    String expectedResult1 = "A";
    String expectedResult2 = "X";
        
    assertThat(actualResult.get(0), either(startsWith(expectedResult1)).or(endsWith(expectedResult2)));
}

19. Combining Matchers using AllOf

A JUnit test method with an assertion that matches if the examined object matches ALL of the specified matchers.

@Test
public final void validateAllOfCollectionValues() {
    List<String> actualResult = Arrays.asList("ABC", "DEF", "GHI");
    String expectedResult1 = "A";
    String expectedResult2 = "C";
    String expectedResult3 = "B";
        
    assertThat(actualResult.get(0), allOf(startsWith(expectedResult1), endsWith(expectedResult2), containsString(expectedResult3)));
}

20. Combining Matchers using AnyOf

A JUnit test method with an assertion that matches if the examined object matches ANY of the specified matchers.

@Test
public final void validateAnyOfCollectionValues() {
    List<String> actualResult = Arrays.asList("ABC", "DEF", "GHI");
    String expectedResult1 = "A";
    String expectedResult2 = "X";
    String expectedResult3 = "Z";
        
    assertThat(actualResult.get(0), anyOf(startsWith(expectedResult1), endsWith(expectedResult2), containsString(expectedResult3)));
}

Summary

The examples listed in this post is not intended to be a complete list of how to make use of the Hamcrest Java Library to write assertions for Collections. This post serves to illustrate some of the more frequent scenarios for writing assertions on Collections. For more information and more examples, please follow me on any of the different social media platforms and feel free to leave comments.