Guide to Hamcrest Library in Java

Introduction

Hamcrest is a powerful library for writing matcher objects that can be used for making assertions in tests. It is commonly used with testing frameworks like JUnit to improve the readability and maintainability of test cases. This guide will cover the installation, basic usage, advanced features, and various use cases of Hamcrest using the latest version. 

Installation

Adding Hamcrest to Your Project

To use Hamcrest, add the following dependency to your pom.xml if you're using Maven:

<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest</artifactId>
    <version>2.2</version> <!-- or the latest version -->
    <scope>test</scope>
</dependency>

For Gradle:

testImplementation 'org.hamcrest:hamcrest:2.2'

Getting Started with Hamcrest

Basic Matchers

Hamcrest provides a variety of matchers that can be used to write expressive tests.

Using assertThat

The assertThat method is used to make assertions using Hamcrest matchers.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class BasicMatchersExample {
    public static void main(String[] args) {
        String name = "Amit";

        assertThat(name, is("Amit"));
        assertThat(name, not("Vikas"));
        assertThat(name, containsString("mit"));
    }
}

Explanation: This example checks that the string name is equal to "Amit", not equal to "Vikas", and contains the substring "mit".

Output:

No output if assertions pass.

Core Matchers

is Matcher

The is matcher is a wrapper to improve readability.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class IsMatcherExample {
    public static void main(String[] args) {
        int age = 25;

        assertThat(age, is(25));
    }
}

Explanation: This example checks that the integer age is equal to 25.

Output:

No output if assertions pass.

equalTo Matcher

The equalTo matcher checks for object equality.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class EqualToMatcherExample {
    public static void main(String[] args) {
        String city = "Mumbai";

        assertThat(city, equalTo("Mumbai"));
    }
}

Explanation: This example checks that the string city is equal to "Mumbai".

Output:

No output if assertions pass.

not Matcher

The not matcher inverts the result of another matcher.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class NotMatcherExample {
    public static void main(String[] args) {
        String name = "Rajesh";

        assertThat(name, is(not("Suresh")));
    }
}

Explanation: This example checks that the string name is not equal to "Suresh".

Output:

No output if assertions pass.

containsString Matcher

The containsString matcher checks if a string contains a specific substring.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class ContainsStringMatcherExample {
    public static void main(String[] args) {
        String message = "Hello, Priya!";

        assertThat(message, containsString("Priya"));
    }
}

Explanation: This example checks that the string message contains the substring "Priya".

Output:

No output if assertions pass.

Advanced Matchers

Collection Matchers

Hamcrest provides several matchers to work with collections.

hasItem Matcher

The hasItem matcher checks if a collection contains a specific item.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import java.util.Arrays;
import java.util.List;

public class HasItemMatcherExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Amit", "Rajesh", "Priya");

        assertThat(names, hasItem("Priya"));
    }
}

Explanation: This example checks that the list names contains the item "Priya".

Output:

No output if assertions pass.

hasItems Matcher

The hasItems matcher checks if a collection contains multiple specific items.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import java.util.Arrays;
import java.util.List;

public class HasItemsMatcherExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Amit", "Rajesh", "Priya");

        assertThat(names, hasItems("Amit", "Priya"));
    }
}

Explanation: This example checks that the list names contains both "Amit" and "Priya".

Output:

No output if assertions pass.

everyItem Matcher

The everyItem matcher checks if every item in a collection matches a specific condition.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import java.util.Arrays;
import java.util.List;

public class EveryItemMatcherExample {
    public static void main(String[] args) {
        List<Integer> ages = Arrays.asList(20, 25, 30);

        assertThat(ages, everyItem(greaterThan(18)));
    }
}

Explanation: This example checks that every item in the list ages is greater than 18.

Output:

No output if assertions pass.

Custom Matchers

Hamcrest allows you to create custom matchers to suit your specific needs.

import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;

public class IsPositiveInteger extends TypeSafeMatcher<Integer> {
    @Override
    protected boolean matchesSafely(Integer number) {
        return number > 0;
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("a positive integer");
    }

    public static IsPositiveInteger isPositiveInteger() {
        return new IsPositiveInteger();
    }
}

Explanation: This custom matcher IsPositiveInteger checks if an integer is positive.

Using the Custom Matcher

import static org.hamcrest.MatcherAssert.assertThat;

public class CustomMatcherExample {
    public static void main(String[] args) {
        int number = 10;

        assertThat(number, IsPositiveInteger.isPositiveInteger());
    }
}

Explanation: This example checks that the integer number is positive using the custom matcher IsPositiveInteger.

Output:

No output if assertions pass.

Logical Matchers

allOf Matcher

The allOf matcher checks if all conditions are met.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class AllOfMatcherExample {
    public static void main(String[] args) {
        String name = "Amit Sharma";

        assertThat(name, allOf(startsWith("Amit"), containsString("Sharma")));
    }
}

Explanation: This example checks that the string name starts with "Amit" and contains "Sharma".

Output:

No output if assertions pass.

anyOf Matcher

The anyOf matcher checks if any of the conditions are met.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class AnyOfMatcherExample {
    public static void main(String[] args) {
        String name = "Amit Sharma";

        assertThat(name, anyOf(startsWith("Amit"), containsString("Kumar")));
    }
}

Explanation: This example checks that the string name either starts with "Amit" or contains "Kumar".

Output:

No output if assertions pass.

String Matchers

startsWith Matcher

The startsWith matcher checks if a string starts with a specific prefix.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class StartsWithMatcherExample {
    public static void main(String[] args) {
        String name = "Suresh Kumar";

        assertThat(name, startsWith("Suresh"));
    }
}

Explanation: This example checks that the string name starts with "Suresh".

Output:

No output if assertions pass.

endsWith Matcher

The endsWith matcher checks if a string ends with a specific suffix.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class EndsWithMatcherExample {
    public static void main(String[] args) {
        String name = "Suresh Kumar";

        assertThat(name, endsWith("Kumar"));
    }
}

Explanation: This example checks that the string name ends with "Kumar".

Output:

No output if assertions pass.

Number Matchers

greaterThan Matcher

The greaterThan matcher checks if a number is greater than a specific value.

import static org.hamcrest.MatcherAssert.assertThat;
import static



 org.hamcrest.Matchers.*;

public class GreaterThanMatcherExample {
    public static void main(String[] args) {
        int age = 30;

        assertThat(age, greaterThan(25));
    }
}

Explanation: This example checks that the integer age is greater than 25.

Output:

No output if assertions pass.

lessThan Matcher

The lessThan matcher checks if a number is less than a specific value.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class LessThanMatcherExample {
    public static void main(String[] args) {
        int age = 20;

        assertThat(age, lessThan(25));
    }
}

Explanation: This example checks that the integer age is less than 25.

Output:

No output if assertions pass. 

closeTo Matcher

The closeTo matcher checks if a number is close to a specific value within a certain delta.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class CloseToMatcherExample {
    public static void main(String[] args) {
        double value = 19.99;

        assertThat(value, closeTo(20.0, 0.1));
    }
}

Explanation: This example checks that the double value is close to 20.0 within a delta of 0.1.

Output:

No output if assertions pass.

Conclusion

Hamcrest is a versatile and powerful library for writing expressive and readable assertions in Java. This guide covered the basics of using Hamcrest with various matchers, including core matchers, collection matchers, custom matchers, logical matchers, string matchers, and number matchers. By leveraging Hamcrest, you can improve the readability and maintainability of your test cases. For more detailed information and advanced features, refer to the official Hamcrest documentation.

Comments