For every configured type the Hamcrest backend generates a matcher, CustomerMatcher for Customer, with two factory methods: isCustomer() for a matcher that checks properties one by one, and isCustomerLike(reference) for a matcher that compares every property with a reference object. The matcher works with Hamcrest’s own assertThat.
Checking one property
A basic assertion checks one property by equality. Each property gets a withX method that takes the expected value:
assertThat(ADA, isCustomer().withName("Ada"));
The withX method also takes any Hamcrest matcher, so you can use the full range of Hamcrest matchers for a property:
assertThat(ADA, isCustomer().withName(startsWith("A")));
A property whose type is itself a generated type takes that type’s matcher, so nested properties are checked the same way:
assertThat(ADA, isCustomer().withAddress(isAddress().withCity("Paris")));
Removing a check
The resetX method removes the check of a property again. The example sets the name check to Bob, which does not match Ada, and the reset removes that check, so the assertion passes:
assertThat(ADA, isCustomer().withName("Bob").resetName());
Completeness check
The completeness check turns a matcher into a check of every property. It is off by default. When you call checkingAllProperties(), the assertion fails unless every property is either checked or ignored. An ignored property is one you name with ignoringX(), so the decision not to check it is visible in the test:
assertThat(
ADA,
isCustomer()
.withName("Ada")
.withAddress(isAddress().withCity("Paris"))
.ignoringActive()
.checkingAllProperties());
When a property was neither checked nor ignored, the failure names it. A property added to the model later therefore fails the tests that opt in, until someone checks or ignores it. The completeness check chapter covers the rule for both backends and the Kotlin DSL.
Reference objects
The isCustomerLike(reference) method takes a reference object and compares every property with it, nested properties included. The example passes because the actual customer equals the reference. A reference that differs in a nested property fails and names that property, as the address.city check in CustomerMatcherTest shows:
assertThat(
ADA,
isCustomerLike(new Customer("Ada", new Address("1 Rue de Rivoli", "Paris"), true)));
A deep comparison applies only to properties whose type has a matcher generated in the same processing round. A property whose type is a class of yours without a generated matcher in the round, for example because it is configured in another round or compilation, is compared with equals instead. Run the compiler with -Amatchergenerator.verbose to get one note per such property that names the property and the type.
Next steps
-
AssertJ backend for the same model as assertions.
-
Configuration for the types the matchers are generated for.