11

I need to write Matcher which will check multiple properties. For single property i've used:

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasProperty;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;

    Matcher<Class> matcherName = Matchers.<Class> hasProperty("propertyName",equalTo(expectedValue));

how am I suppose to check more properties in one Matcher ?

Szympek
  • 183
  • 1
  • 2
  • 7

2 Answers2

25

You can check for more properties using one matcher by combining matchers with allOf:

    Matcher<Class> matcherName = allOf(
        hasProperty("propertyName", equalTo(expected1)),
        hasProperty("propertyName2", equalTo(expected2)));

But I guess that what you are actually looking for is the samePropertyValuesAs one, that checks if a bean has the same property values as another one by checking the properties itself instead of the equals method:

    assertThat(yourBean, samePropertyValuesAs(expectedBean));
Ruben
  • 3,986
  • 1
  • 21
  • 34
  • Yes, allOf is good way, but I cant use assertThat i need to verify if object run method with expected parameter, like: `verify(mock).method(argThat(matcherName));` – Szympek Feb 17 '16 at 08:55
  • @Szympek `samePropertyValuesAs` is also a `Matcher` that you can assign to a variable: `Matcher matcherName = samePropertyValuesAs(expectedBean)` – Ruben Feb 21 '16 at 13:03
5

Ruben's answer using allOf is the best way to combine matchers, but you may also choose to write your own matcher from scratch based on BaseMatcher or TypeSafeMatcher:

Matcher<Class> matcherName = new TypeSafeMatcher<Class>() {
  @Override public boolean matchesSafely(Class object) {
    return expected1.equals(object.getPropertyName())
        && expected2.equals(object.getPropertyName2());
  }
};

Though you do get unlimited power to write arbitrary matcher code without relying on reflection (the way that hasProperty does), you'll need to write your own describeTo and describeMismatch(Safely) implementations to get the comprehensive error messages that hasProperty defines and that allOf would aggregate for you.

You may find it wise to use allOf for simple cases involving a couple of simple matchers, but consider writing your own if matching a large number of properties or if implementing complex conditional logic.

Community
  • 1
  • 1
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251