Java中Matrix类JUnit测试值一致但assertEquals断言失败如何解决
问题原因
你遇到的问题本质是assertEquals方法判断对象相等的逻辑问题:
- JUnit的
assertEquals对比两个自定义类对象时,会调用类的equals()方法,如果你没有为Matrix类重写equals()方法,会默认使用Object类的原生实现,该实现仅对比两个对象的内存地址,不会校验对象内部的属性值。 - 你看到的报错信息中两个对象内容显示一致,是因为你重写了
Matrix类的toString()方法,打印时会输出内部数组的内容,但这不影响equals()方法的判断逻辑。 - 补充注意:就算你重写
equals()方法时直接调用数组的equals()方法也会有问题,因为Java数组的默认equals()同样是对比内存地址,二维数组需要深度比较内容。
解决方案
有两种常用的修复方案,你可以根据需求选择:
方案1:重写Matrix类的equals()和hashCode()方法
这是最符合面向对象规范的方案,重写后可以直接用assertEquals对比Matrix对象:
import java.util.Arrays; import java.util.Objects; public class Matrix { private int[][] matrix; // 你原来的构造方法 public Matrix(int[][] array) { // 这里补充提示:原构造是浅拷贝,如需深度拷贝可以替换为深度拷贝逻辑,不影响本次问题修复 this.matrix = Arrays.copyOf(array, array.length); } // 新增getter方法,可选,方案2会用到 public int[][] getMatrix() { return matrix; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Matrix matrix1 = (Matrix) o; // 用deepEquals深度对比二维数组内容 return Arrays.deepEquals(matrix, matrix1.matrix); } @Override public int hashCode() { // 深度计算二维数组的hash值 return Arrays.deepHashCode(matrix); } // 你原来的toString、addValue等其他方法 }
重写完之后再运行测试,assertEquals(expected, result.addValue(0,4))就可以正常判断内容相等了。
方案2:测试时直接对比内部数组内容
如果你不想修改Matrix类的代码,可以调整测试逻辑,直接对比两个Matrix内部的二维数组:
@Test void addValue() { int[][] array = {{1, 2, 3}, {1, 2, 3}}; int[][] newArray = {{1, 2, 3, 4}, {1, 2, 3}}; Matrix result = new Matrix(array); Matrix expected = new Matrix(newArray); // 直接对比内部二维数组的内容,不需要修改Matrix类的equals方法 org.junit.jupiter.api.Assertions.assertArrayEquals(expected.getMatrix(), result.addValue(0,4).getMatrix()); }
注意这个方案需要你给Matrix类新增一个getMatrix()的公共方法,返回内部存储的二维数组。
内容的提问来源于stack exchange,提问作者Pedro Diniz
相关产品推荐
相关产品推荐

