isEqualToComparingFieldByField is failing but isEqualToComparingFieldByFieldRecursively is passing

user889829 picture user889829 · Mar 15, 2018 · Viewed 7.3k times · Source

I am writing a test using rest-assured to test an API. I have the expected response stored as a String that I convert to an object using google gson and then I use assertj's isEqualToComparingFieldByField to assert that the objects are equal.

Even though the objects fields values are identical the test is failing.What is very strange is that when i call isEqualToComparingFieldByFieldRecursively the test passes? I would be Ok with using isEqualToComparingFieldByFieldRecursively but for my next test I need to use isEqualToIgnoringGivenFields.

Here is the exception I get when calling isEqualToComparingFieldByField.

Expecting values:
<[test.api.pojo.template.Template@42cc420b,
test.api.pojo.template.Status@6f2d3391]>
in fields:
<["template", "status"]>
but were:
<[test.api.pojo.template.Template@71b0289b,
test.api.pojo.template.Status@ae3c140]>
in test.api.pojo.template.TemplateResponse@2c9cafa5>.

and here is the code for the test

RequestSpecification request = given()
            .spec(spec)
            .pathParam("name", "abc");

Response response = request.when().get(ENDPOINT_GET_TEMPLATE);

String expectedResponseStr =  "{ \"id\": 1247,"
    + "\"versionNumber\": 0,"
    + "\"template\": {";//...

String actualResponseStr = response.asString();
assertThat(actualResponseStr).isEqualTo(expectedResponseStr); //this passes 


TemplateResponse expectedResponseObj = convertToObj(expectedResponseStr, TemplateResponse.class);
TemplateResponse actualResponseObj = response.then().extract().as(TemplateResponse.class);

assertThat(actualResponseObj)
    .isEqualToComparingFieldByFieldRecursively(expectedResponseObj); //this passes

assertThat(actualResponseObj)
    .isEqualToComparingFieldByField(expectedResponseObj); //this fails with 

Answer

Joel Costigliola picture Joel Costigliola · Mar 16, 2018

isEqualToComparingFieldByField will use fields equals method which I suspect are not overridden in Status and Template, this means that for the test to pass they must be the same reference (they are not according to the error message).

On the other hand, isEqualToComparingFieldByFieldRecursively only uses equals methods when they are overridden otherwise it compares fields by fields, the test passesas actual Status / Template and expected ones have the same fields values.