如何在没有 equals 方法的情况下断言两个类的相等性?

新手上路,请多包涵

假设我有一个没有 equals() 方法的类,它没有源代码。我想断言该类的两个实例相等。

我可以做多个断言:

 assertEquals(obj1.getFieldA(), obj2.getFieldA());
assertEquals(obj1.getFieldB(), obj2.getFieldB());
assertEquals(obj1.getFieldC(), obj2.getFieldC());
...

我不喜欢这个解决方案,因为如果早期断言失败,我就无法获得完整的平等图景。

我可以自己手动比较并跟踪结果:

 String errorStr = "";
if(!obj1.getFieldA().equals(obj2.getFieldA())) {
    errorStr += "expected: " + obj1.getFieldA() + ", actual: " + obj2.getFieldA() + "\n";
}
if(!obj1.getFieldB().equals(obj2.getFieldB())) {
    errorStr += "expected: " + obj1.getFieldB() + ", actual: " + obj2.getFieldB() + "\n";
}
...
assertEquals("", errorStr);

这给了我完整的平等图,但很笨拙(我什至没有考虑可能的空问题)。第三种选择是使用 Comparator,但 compareTo() 不会告诉我哪些字段不相等。

有没有更好的做法可以从对象中获得我想要的东西,而无需子类化和覆盖等于(呃)?

原文由 Ryan Nelson 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 479
1 个回答

这里有很多正确答案,但我也想添加我的版本。这是基于 Assertj 的。

 import static org.assertj.core.api.Assertions.assertThat;

public class TestClass {

    public void test() {
        // do the actual test
        assertThat(actualObject)
            .isEqualToComparingFieldByFieldRecursively(expectedObject);
    }
}

更新:在 assertj v3.13.2 中,正如 Woodz 在评论中指出的那样,此方法已弃用。目前的建议是

public class TestClass {

    public void test() {
        // do the actual test
        assertThat(actualObject)
            .usingRecursiveComparison()
            .isEqualTo(expectedObject);
    }

}

原文由 Thomas 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题