Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to do deep comparison on a nested property with Hamcrest

I use hamcrest for most of my testing ,but have encountered a issue with it not being able to test a property one level down in the object graph .A snipped of my test case is below

final List<Foo> foos= fooRepository.findAll(spec);
      assertThat(results, is(notNullValue()));
      assertThat(results, hasItem(hasProperty("id.fooID1", equalTo("FOOID1"))));

so here I want to check if in the list of foos I have a property id.fooID1 equla to FOOID1 .Here I am going one level down to check my nested property .This doesnt currently work in hamcrest and I get the following error.

java.lang.AssertionError: 
Expected: a collection containing hasProperty("id.fooID1", "FOOID1")
     but: No property "id.fooID1"
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
    at org.junit.Assert.assertThat(Assert.java:956)
    at org.junit.Assert.assertThat(Assert.java:923)

any help or workaround on this issue .

like image 511
Gaurav Rawat Avatar asked Apr 01 '16 18:04

Gaurav Rawat


2 Answers

You can nest hasProperty calls:

assertThat(results, hasItem(hasProperty("id", hasProperty("fooID1", equalTo("FOOID1")))));

For deeper nestings this might be a bit unwieldy.

like image 87
eee Avatar answered Oct 22 '22 23:10

eee


I've achieved the result you expected with this simple utility method:

private static <T> Matcher<T> hasGraph(String graphPath, Matcher<T> matcher) {

    List<String> properties = Arrays.asList(graphPath.split("\\."));
    ListIterator<String> iterator =
        properties.listIterator(properties.size());

    Matcher<T> ret = matcher;
    while (iterator.hasPrevious()) {
        ret = hasProperty(iterator.previous(), ret);
    }
    return ret;
}

which I am able to use in asserts like this:

 assertThat(bean, hasGraph("beanProperty.subProperty.subSubProperty", notNullValue()));

check if this is of any help

like image 29
Cristiano Costantini Avatar answered Oct 22 '22 22:10

Cristiano Costantini