如何使用 reflectionEquals 检查 2 个对象中的所有字段是否相等?
How to check all fields in 2 objects are equal using reflectionEquals?
我正在编写一个 JUnit
测试,我想测试 2 个对象中的所有字段 是否相等。
我试过以下方法:
@Test
public void testPersonObjectsAreEqual(){
Person expectedPerson = new Person("100100", "sampleName", "sampleAddress");
Person actualPersonReturned = repository.getPersonById("100100");
Assert.assertTrue(EqualsBuilder.reflectionEquals(expectedPerson, actualPersonReturned));
}
但是测试失败了,即使 2 个对象中的字段相同。
他们都有:100100
、sampleName
和sampleAddress
simplest/the 最首选的方法是在您断言的所有 类 中覆盖 equals()
(和 hashCode()
)(包括嵌套的 类 ) 并使用 Assert.assertEquals(expected, actual)
.
2 个字段的比较失败的原因是因为 EqualsBuilder.reflectionEquals(Object lhs, Object rhs)
正在进行浅比较,并且在您的实际代码中 Person
引用了一个 Address
实例,它确实尚未 equals()
实施。
在Person中写equals,hashCode方法class判断对象是否相等
您可以使用 assertEquals 而不是 assertTrue 进行测试
@Test
public void testPersonObjectsAreEqual(){
Person expectedPerson = new Person("100100", "sampleName", "sampleAddress")
Person actualPersonReturned = repository.getPersonById("100100);
Assert.assertEquals(expectedPerson, actualPersonReturned);
}
EqualsBuilder#reflectionEquals()
有很多变化。
考虑排除不需要的属性。然后你可以精确比较2个对象。
您也可以在您的特定 class 中使用简单的 equals()
覆盖并执行相同的操作。
在您的示例中,您需要覆盖 class Person 中的 equals 方法(如果 Person 对象的属性都相等则返回 true)。例如:
public class Person {
private String name;
private String surname;
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (surname == null) {
if (other.surname != null)
return false;
} else if (!surname.equals(other.surname))
return false;
return true;
}
}
您可以使用 IDE 自动完成,前面的代码片段是使用 Eclipse 自动生成的。
就个人而言,我会为此使用自定义匹配器
@Test
public void testPersonObjectsAreEqual(){
Person expectedPerson = new Person("100100", "sampleName", "sampleAddress")
Person actualPersonReturned = repository.getPersonById("100100");
assertThat(actualPersonReturned, is(matchingPerson(expectedPerson)));
}
private Matcher<Person> matchingPerson(Person expected) {
return new TypeSafeMatcher<Person>() {
public boolean matchesSafely(Person actual) {
return actual.getId().equals(expected.getId())
&& actual.getName().equals(expected.getName();
&& actual.getAddress().equals(expected.getAddress();
}
public void describeMismatchSafely(Person person, Description mismatchDescription) {
mismatchDescription.appendText("give a meaningful message");
}
};
}
您可以使用一个名为 Unitils 的不错的库,它可以很好地记录错误并提供详细信息
User user1 = new User(1, "John", "Doe");
User user2 = new User(1, "John", "Doe");
assertReflectionEquals(user1, user2);
易于使用,不需要覆盖 equals 和 hash 方法。
此断言遍历两个对象中的所有字段并使用反射比较它们的值。对于上面的示例,它将首先比较两个 id 字段值,然后比较第一个字段值,最后比较两个最后字段值。
对于 Kotlin,您可以使用 Mockito 的匹配器:
@Test
fun someEqualsTest(){
val actual = ...
val expected = ...
assertTrue(ReflectionEquals(actual).matches(expected))
}
我正在编写一个 JUnit
测试,我想测试 2 个对象中的所有字段 是否相等。
我试过以下方法:
@Test
public void testPersonObjectsAreEqual(){
Person expectedPerson = new Person("100100", "sampleName", "sampleAddress");
Person actualPersonReturned = repository.getPersonById("100100");
Assert.assertTrue(EqualsBuilder.reflectionEquals(expectedPerson, actualPersonReturned));
}
但是测试失败了,即使 2 个对象中的字段相同。
他们都有:100100
、sampleName
和sampleAddress
simplest/the 最首选的方法是在您断言的所有 类 中覆盖 equals()
(和 hashCode()
)(包括嵌套的 类 ) 并使用 Assert.assertEquals(expected, actual)
.
2 个字段的比较失败的原因是因为 EqualsBuilder.reflectionEquals(Object lhs, Object rhs)
正在进行浅比较,并且在您的实际代码中 Person
引用了一个 Address
实例,它确实尚未 equals()
实施。
在Person中写equals,hashCode方法class判断对象是否相等
您可以使用 assertEquals 而不是 assertTrue 进行测试
@Test
public void testPersonObjectsAreEqual(){
Person expectedPerson = new Person("100100", "sampleName", "sampleAddress")
Person actualPersonReturned = repository.getPersonById("100100);
Assert.assertEquals(expectedPerson, actualPersonReturned);
}
EqualsBuilder#reflectionEquals()
有很多变化。
考虑排除不需要的属性。然后你可以精确比较2个对象。
您也可以在您的特定 class 中使用简单的 equals()
覆盖并执行相同的操作。
在您的示例中,您需要覆盖 class Person 中的 equals 方法(如果 Person 对象的属性都相等则返回 true)。例如:
public class Person {
private String name;
private String surname;
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (surname == null) {
if (other.surname != null)
return false;
} else if (!surname.equals(other.surname))
return false;
return true;
}
}
您可以使用 IDE 自动完成,前面的代码片段是使用 Eclipse 自动生成的。
就个人而言,我会为此使用自定义匹配器
@Test
public void testPersonObjectsAreEqual(){
Person expectedPerson = new Person("100100", "sampleName", "sampleAddress")
Person actualPersonReturned = repository.getPersonById("100100");
assertThat(actualPersonReturned, is(matchingPerson(expectedPerson)));
}
private Matcher<Person> matchingPerson(Person expected) {
return new TypeSafeMatcher<Person>() {
public boolean matchesSafely(Person actual) {
return actual.getId().equals(expected.getId())
&& actual.getName().equals(expected.getName();
&& actual.getAddress().equals(expected.getAddress();
}
public void describeMismatchSafely(Person person, Description mismatchDescription) {
mismatchDescription.appendText("give a meaningful message");
}
};
}
您可以使用一个名为 Unitils 的不错的库,它可以很好地记录错误并提供详细信息
User user1 = new User(1, "John", "Doe");
User user2 = new User(1, "John", "Doe");
assertReflectionEquals(user1, user2);
易于使用,不需要覆盖 equals 和 hash 方法。 此断言遍历两个对象中的所有字段并使用反射比较它们的值。对于上面的示例,它将首先比较两个 id 字段值,然后比较第一个字段值,最后比较两个最后字段值。
对于 Kotlin,您可以使用 Mockito 的匹配器:
@Test
fun someEqualsTest(){
val actual = ...
val expected = ...
assertTrue(ReflectionEquals(actual).matches(expected))
}