-
Notifications
You must be signed in to change notification settings - Fork 1
Hamcrest extension for Guava
This page describes the Hamcrest extension for JDK7.
To start using the extension for JDK7, simply import the following dependency in your pom.xml
.
<dependency>
<artifactId>it.ozimov</artifactId>
<artifactId>cirneco-hamcrest-jdk7</artifactId>
<version>0.2</version>
<scope>test</scope>
</dependency>
If you don't use Maven, go here to see how to import using another build automation tool (e.g. Gradle, Grape, etc.).
If you prefer, you can directly import the jar from here:
Once that you have the jar available, in your unit test class you should import all the new matchers as follows:
import static it.ozimov.cirneco.assertions.hamcrest.CirnecoMatchersJ7.*;
There may be a clash with the firm of such another statically imported method from another library, in this case proceed as by practice.
The library provides matchers divided into the following categories
- Base - Basic matchers for standard JDK7 classes and Guava base classes.
-
Date - Matchers for
Date
. -
Iterable - Matchers for
Iterable
and some Guava'sIterable
implementation, likeMultiset
. -
Map - Matchers for
Map
and Guava'sMultimap
. -
Number - Matchers for
Number
objects, i.e. integers and floating numbers. - Web - Matchers for Web-oriented objects, i.e. emails.
In Cirneco there is a category of general purpose matchers for asserting that an object is between another two objects. The category includes four matchers:
These matchers can be applied to numbers, dates and more in general to any other object that implements Comparable
.
An example follows.
//Arrange
Date yesterday = ...; //Init date with date of yesterday
Date tomorrow = ...; //Init date with date of tomorrow
//Act
Date today = methodThatReturnsNow();
//Assert
assertThat("Expected the today to be between yesterday and tomorrow",
today, between(yesterday, tomorrow));
The Guava users may take benefit of the emptyGuavaOptional()
matcher. Every time that a method returns an com.google.common.base.Optional
, it is convenient to check that the returned Optional
is or is not empty as follows:
//Act
Optional optional = methodThatReturnsOptional();
//Assert
assertThat("Expected the returned optional not to be empty",
optional, not(is(emptyGuavaOptional()));
Another matchers based on an useful Guava feature is equivalentTo()
matcher. Sometimes is convenient to compare objects based on a subset of the object properties.
E.g., suppose to have an entity from a DB and another that has the same fields except the id. Clearly, the equals()
method from Object
should return false
comparing these two objects. However, you can use com.google.common.base.Equivalence
to write down a custom equivalence checker that amends the id from the comparison. The following example shows this use case.
//Arrange
Equivalence<MyEntity> entityEquivalence; //Initialize an Equivalence
MyEntity persistedEntity = DAO.findById(1); //retrieve a MyEntity by id from the DB
//Act
MyEntity nonPersistedEntity = methodThatCreateAnEntityWithoutId();
//Assert
assertThat("Expected the two instances to be equivalent",
nonPersistedEntity, equivalentTo(pesistedEntity, entityEquivalence));
The Hamcrest library already provides a couple of matchers to verify that two objects are the same, i.e. sameInstance()
and theInstance()
(they are equivalent). Unfortunately both require the instances to be of the same type. This will prevent the possibility to compare the same instance when downcasted to a parent class or interface. Thus, Cirneco provides a new matcher, sameInstance()
, to recover from this situation.
Here follows an example.
//Arrange
ArrayList<Object> arrayList = new ArrayList<>();
List<Object> list = arrayList; //Same object as arrayList
//Assert
assertThat("Expected list to be the same instance of arrayList",
list, sameInstance(arrayList));
Cirneco provides a lot of matchers for Date
. Generally speaking, these matchers are there to provide support to simple date comparison assertions (e.g. to assert that is specific day of the week) or more complex ones (e.g. is a date with given hour and minute).
Cirneco provides a set of matchers to assert that a Date
object is in a specific year, month or day. The IsDate
matcher has a flexible constructor that let you to formulate matchers for all the combinations of the fields year, month and day. For instance, if you want to be sure that now is a day 28
of year 2015
, you can do as follows:
//Arrange
Date date = new Date(); //Don't do it at home :)
int expectedDay = 28;
int expectedMonth = null;
int expectedYear = 2015;
//Assert
assertThat("Expected that today is day 28 of any month of year 2015",
now, new IsDate(expectedYear, expectedMonth, expectedDay));
Clearly, there are some convenience static method that can be used without invoking the constructor. They are listed here:
-
hasYear(int year)
. -
hasMonth(int month)
. -
hasDay(int day)
. -
hasYearAndMonth(int year, int month)
. -
hasYearMonthAndDay(int year, int month, int day)
. -
hasMonthAndDay(int year, int month, int day)
.
In a similar way as for the year, month and day matchers, there are a set of matchers to assert that a Date
object is in a specific hour, minute, second or millisecond. The IsDateWithTime
matcher has a flexible constructor that let you to formulate matchers for all the combinations of the fields hour, minute, second and millisecond. For instance, if you want to be sure that now is is hour 16
and second 59
(of any minute), you can do as follows:
//Arrange
Date date = new Date(); //Don't do it at home :)
int expectedHour = 16;
int expectedMinute = null;
int expectedSecond = 59;
int expectedMillisecond = null;
//Assert
assertThat("Expected that now hour 16 and second 59 of any minute and millisecond",
now, new IsDateWithTime(expectedHour, expectedMinute, expectedSecond, expectedMillisecond);
Moreover, we support also the 12-hours clock period. So, the previous example would be
//Arrange
Date date = new Date(); //Don't do it at home :)
int expectedHour = 4;
ClockPeriod clockPeriod = ClockPeriod.PM;
int expectedMinute = null;
int expectedSecond = 59;
int expectedMillisecond = null;
//Assert
assertThat("Expected that now hour 16 and second 59 of any minute and millisecond",
now, new IsDateWithTime(expectedHour, clockPeriod, expectedMinute, expectedSecond, expectedMillisecond);
Observer that by default the 24-hours clock period is considered.
To make life easier, there is a set of convenience static method that can be used without invoking the constructor. They are listed here:
-
hasHour(int hour)
. -
hasHour(int hour, ClockPeriod clockPeriod)
. -
hasMinute(final int minute)
. -
hasSecond(final int second)
. -
hasMillisecond(final int millisecond)
. -
hasHourAndMin(int hour, final int minute)
. -
hasHourAndMin(int hour, final ClockPeriod clockPeriod, int minute)
. -
hasHourMinAndSec(int hour, int minute, int second)
. -
hasHourMinAndSec(int hour, ClockPeriod clockPeriod, int minute, int second)
. -
hasHourMinSecAndMillis(int hour, int minute, int second, int millisecond)
. -
hasHourMinSecAndMillis(int hour, ClockPeriod clockPeriod, int minute, int second, int millisecond)
.
To assert that a Date
object is a leap year, the matcher leapYear()
is provided. A simple example follows:
//Arrange
Date date = new Date();
//Assert
assertThat("Expected a leap year", date, leapYear());
To assert that a Date
object is in a specific week of the year (i.e. a number between 1 and 53 according to the ISO 8601 standard), the matcher inWeekOfYear()
is provided. A simple example follows:
//Act
Date date = methodThatReturnsFirstOfJanuary2016();
//Assert
assertThat("Expected 2016-01-01 to be in week 53 of the year (2015)", date, IsDateInWeekOfYear.inWeekOfYear(53));
To assert that Date
object is in a specific month of the year, the twelve matchers january()
, february()
, ..., december()
are provided. A simple example follows:
//Arrange
Date date = new Date();
//Assert
assertThat("Expected the date to be in the month August", date, august());
To assert that Date
object is in a specific day of the week, the seven matchers monday()
, tuesday()
, ..., sunday()
are provided. A simple example follows:
//Arrange
Date date = new Date();
//Assert
assertThat("Expected the date to be in the day Friday", date, friday());
Cirneco provides some matchers for the interface Iterable
. Hamcrest very often differentiates between matchers for interfaces Iterable
and Collection
, even if the latter extends the latter. Hence, we find more convenient to provide matchers for the former and eventually check if an instance of a Collection
is given to get some benefit from methods specifically provided by this interface.
Moreover, some matchers that can be obtained using the base one are now provided ready to use (e.g. see hasSizeOne()
).
Cirneco provides the empty()
matcher. It is nothing really new, since Hamcrest has emptyIterable()
, but is more easy-to-read and internally calls isEmpty()
on the given Iterable
whenever it is an instance of a Collection
to gain some eventual speed-up.
The common use for this matcher would be:
//Arrange
List<Integer> list = new ArrayList<>();
//Assert
assertThat("Expected empty list", list, empty());
To assert that an Iterable contains only distinct elements (i.e. has no duplicates), Cirneco provides the [
hasDistinctElements()()`](http://ozimov.github.io/cirneco/it/ozimov/cirneco/hamcrest/iterable/IsIterableWithDistinctElements.html#hasDistinctElements--) matcher.
The common use for this matcher would be:
//Arrange
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
//Assert
assertThat("Expected list without duplicates", list, hasDistinctElements()); //Success
Hamcrest provides a matcher to check the size of a Collection
(i.e. see hasSize()
) and of an Iterable
(see iterableWithSize()
), but the latter doesn't take any benefit from the type of Iterable
(i.e., if it is a Collection
you can still use method size()
). Cirneco provides new matchers aimed by the same spirit, but more general and effective. In fact, the new matchers are designed to work with any Iterable
but to eventually take benefit of the actual implementation.
So, you can use hasSize()
also for an Iterable
, e.g.
//Arrange
List<Integer> list = new ArrayList<>();
list.add(1);
//Assert
assertThat("Expected list with size 1", list, hasSize(1));
but if you are lazy you can use hasSizeOne()
, hasSizeTwo()
, ..., hasSizeFive()
. Even if this seems not really useful or redundant, it is very convenient, for at least two reasons: i) it is more easy-to-read and ii) a good IDE (e.g. IntelliJ) can let you type the initials of the matcher to get it from a dropdown from the autocompletion widget (e.g typing "hso" the hasSizeOne()
matcher will appear). So, the previous example is equivalent to the following code.
//Arrange
List<Integer> list = new ArrayList<>();
list.add(1);
//Assert
assertThat("Expected list with size 1", list, hasSizeOne());
In a Multiset
each element has a count. To assert that an element has a given count, the elementWithCount()
matcher is provided. A simple example is provided.
//Act
Multiset<String> multiset = methodThatReturnsAMultiset();
//Assert
assertThat("Expected that element \"A\" in the multiset has count 10", multiset, elementWithCount("A", 10));
Cirneco introduces new matchers to ascertain that a given Iterable
is sorted or sorted in reverse order, with matchers sorted()
and sortedReversed()
, respectively. These matchers must be used on an Iterable
of objects that implement Comparable
If an Iterable
of whatsoever objects is given, by verifying that it is sorted it can be used a Comparator
along with the two matchers that accept a Comparator
, i.e. sorted()
and sortedReversed()
.
Some examples follow:
//Arrange
List<Integer> list = new ArrayList<>(); //Integer implements Comparable
list.add(1);
list.add(2);
list.add(3);
//Assert
assertThat("Expected list to be sorted by using the natural ordering of Integer",
list, sorted());
Or with a Comparator
you can do as follows.
//Arrange
Comparator<MyObject> comparator; //Init somehow a comparator for class MyObject.
List<MyObject> list = new ArrayList<>(); //MyObject may not implement Comparable
list.add(...);//Init the list
//Assert
assertThat("Expected list to be sorted by using a custom Comparator for class MyObject",
list, sorted(comparator));
The reversed sorting is asserted by the sortedReversed()
version of the matcher.
Sometimes it is convenient to assert that two maps have the same keyset. Thus, here comes the new matcher
hasSameKeySet()
. The following example shows a possible use case.
//Arrange
Map<String, Integer> comparisonMap = new HashMap<>();
map.put("A", 1);
map.put("B", 2);
//Act
Map<String, Number> actualMap = methodReturningMap();
//Assert
assertThat("Expected actualMap to have the same keyset of comparisonMap",
actualMap, hasSameKeySet(comparisonMap));
In a Multimap
, each key maps a Collection
of objects. To assert that the size of the collection of a map key is a given value, the matcher
keyWithSize()
is introduced. An examples follows
//Arrange
String key = "AKey";
Collection<Integer> valuesForKey = ImmutableList.of(1, 100, 100_000);
Multimap<String, Integer> multimap = ArrayListMultimap.create();
//Act
multimap.put("AKey", valuesForKey);
//Assert
assertThat(String.format("Expected a collection size for key \"%s\" equals to 3", key),
multimap, keyWithSize(key, 3));
To assert that a Multimap
has a given keyset, the matcher
hasSameKeySet()
can be used. It works with both another Multimap
or with a Set
. E.g.
//Arrange
Set<String> expectedKeySet = ImmutableSet.of("A", "B", "C");
//Act
Multimap<String, Integer> multimap = methodReturningMultimap;
//Assert
assertThat("Expected a multimap with keyset [\"A\", \"B\", \"C"\]",
multimap, hasSameKeySet(expectedKeySet));
To deal with the size of the keyset of a Multimap
, the matchers emptyKeySet()
and keySetWithSize()
are provided. An example follows.
//Act
Multimap<String, Integer> multimap = methodReturningMultimap;
//Assert
assertThat("Expected a multimap with non-empty keyset",
multimap, not(emptyKeySet()));
assertThat("Expected a multimap with keyset with size 1",
multimap, keySetWithSize(1));
To assert that a Number
is positive or negative, the positive()
and negative()
matchers have been added, respectively.
To assert that a Number
is infinity you can use the new infinity()
matcher. An example follows.
//Act
Double number = methodReturningADouble();
//Assert
assertThat("Expected a number equals to positive or negative infinity", number, infinity());
You can be more specific with the matchers negativeInfinity()
and positiveInfinity()
.
To assert that a Number
does not represent a numeric value you can use the notANumber()
matcher.
This category of matchers aims to support libraries for web based applications. Actually contains only one matcher, but the aim is for a complete coverage of necessary matchers
The email()
matcher aims to assert that a given object has a toString()
method that returns a valid email address. The matcher uses the Apache email validatorApache email validator. This validator doesn't cover all the possible email addresses. If you are not validating very strange email addresses (are you a spammer?!?) then you can safely use this matcher as long as you trust the Apache validator.
An example follows.
//Assert
assertThat("[email protected]", email());