Matching multiple properties in one Matcher
Asked Answered
D

2

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 ?

Disentitle answered 16/2, 2016 at 15:52 Comment(0)
S
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));
Seaton answered 16/2, 2016 at 17:52 Comment(2)
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));Disentitle
@Disentitle samePropertyValuesAs is also a Matcher that you can assign to a variable: Matcher<Class> matcherName = samePropertyValuesAs(expectedBean)Seaton
H
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.

Hath answered 16/2, 2016 at 18:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.