英文:
Unit Testing - AssertionFailedError - Java
问题
我不明白为什么这个单元测试无法正常工作。
我创建了两个@RegionWithActivities实例,我认为它应该通过测试。
@Test
void testAreEqual()
{
RegionWithActivities regionWithActivities1 = new RegionWithActivities(4, regions);
RegionWithActivities regionWithActivities2 = new RegionWithActivities(4, regions);
assertEquals(regionWithActivities1, regionWithActivities2);
}
错误信息如下:
org.opentest4j.AssertionFailedError: 期望: com.luciaandres.analysis.RegionWithActivities@710726a3<RegionWithActivities{numberOfActivities=4, regionIds=[4DA19B2B1328127FC062FB79F6F435A5, B66FA66DA650717E0964A4E30A716DAE, C841C0BED1CCDD643955065A696EED34, F2D04F76EA1EBD6C8E3AEDD506FBA35A]}>,实际: com.luciaandres.analysis.RegionWithActivities@646007f4<RegionWithActivities{numberOfActivities=4, regionIds=[4DA19B2B1328127FC062FB79F6F435A5, B66FA66DA650717E0964A4E30A716DAE, C841C0BED1CCDD643955065A696EED34, F2D04F76EA1EBD6C8E3AEDD506FBA35A]}>
Expected: RegionWithActivities{numberOfActivities=4, regionIds=[4DA19B2B1328127FC062FB79F6F435A5, B66FA66DA650717E0964A4E30A716DAE, C841C0BED1CCDD643955065A696EED34, F2D04F76EA1EBD6C8E3AEDD506FBA35A]}
Actual: RegionWithActivities{numberOfActivities=4, regionIds=[4DA19B2B1328127FC062FB79F6F435A5, B66FA66DA650717E0964A4E30A716DAE, C841C0BED1CCDD643955065A696EED34, F2D04F76EA1EBD6C8E3AEDD506FBA35A]}
at RegionWithActivitiesTest.testAreEqual(RegionWithActivitiesTest.java:29)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
你能解释一下吗?谢谢!
英文:
I'm having troubles understanding why this unit test is not working.
I'm creating two instances of @RegionWithActivities and I thought that it should pass the test.
@Test
void testAreEqual()
{
RegionWithActivities regionWithActivities1 = new RegionWithActivities(4, regions);
RegionWithActivities regionWithActivities2 = new RegionWithActivities(4, regions);
assertEquals(regionWithActivities1, regionWithActivities2);
}
The error is:
org.opentest4j.AssertionFailedError: expected: com.luciaandres.analysis.RegionWithActivities@710726a3<RegionWithActivities{numberOfActivities=4, regionIds=[4DA19B2B1328127FC062FB79F6F435A5, B66FA66DA650717E0964A4E30A716DAE, C841C0BED1CCDD643955065A696EED34, F2D04F76EA1EBD6C8E3AEDD506FBA35A]}> but was: com.luciaandres.analysis.RegionWithActivities@646007f4<RegionWithActivities{numberOfActivities=4, regionIds=[4DA19B2B1328127FC062FB79F6F435A5, B66FA66DA650717E0964A4E30A716DAE, C841C0BED1CCDD643955065A696EED34, F2D04F76EA1EBD6C8E3AEDD506FBA35A]}>
Expected :RegionWithActivities{numberOfActivities=4, regionIds=[4DA19B2B1328127FC062FB79F6F435A5, B66FA66DA650717E0964A4E30A716DAE, C841C0BED1CCDD643955065A696EED34, F2D04F76EA1EBD6C8E3AEDD506FBA35A]}
Actual :RegionWithActivities{numberOfActivities=4, regionIds=[4DA19B2B1328127FC062FB79F6F435A5, B66FA66DA650717E0964A4E30A716DAE, C841C0BED1CCDD643955065A696EED34, F2D04F76EA1EBD6C8E3AEDD506FBA35A]}
at RegionWithActivitiesTest.testAreEqual(RegionWithActivitiesTest.java:29)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
Could you please explain me?
Thanks!
答案1
得分: 2
使用assertEquals时,它尝试使用equals()方法来比较两个对象。如果您的类中没有重写Object类中的equals()方法,它将使用Object类的默认equals()方法,其实现如下:
public boolean equals(Object obj) {
return (this == obj);
}
正如您所见,在这里它只是比较对象引用,因为在您的情况下两个对象具有两个不同的引用,所以断言失败了,因此您需要在RegionWithActivities类中实现equals()方法,并且作为最佳实践,当您重写equals()时,还应该重写hashcode()方法,但对于您的断言是否通过,重写hashcode()方法并不是必要的。
英文:
When you use assertEquals ,it tries to compare two objects using equals() method.If you have not overriden equals() method from Object class in your class,the it uses the default equals() method from Object class which has implementation as below :
public boolean equals(Object obj) {
return (this == obj);
}
As you can see, here it just compares object reference and because two objects have two different references in your case, the assertion is failing, so you need to implement equals() method in RegionWithActivities class and as a best practice when you override equals(), you should override hashcode() method as well, but it is not necessary for your assertion to pass.
答案2
得分: 0
理论上,可以只在 RegionWithActivities
中实现 equals
,使得你的测试案例通过,因为 assertEquals
是基于 RegionWithActivities
的 equals()
进行断言的。但是,仅实现 equals()
而不实现 hashcode()
将会违反Object类契约中的第2条,如下所述:
> hashCode的一般约定如下:
- 在Java应用程序执行期间,对同一对象多次调用hashCode方法时,只要在equals比较期间使用的对象信息未被修改,hashCode方法必须一致地返回相同的整数。这个整数不需要在一个应用程序的多次执行之间保持一致。
- 如果两个对象根据equals(Object)方法是相等的,则对这两个对象中的每个对象调用hashCode方法必须产生相同的整数结果。
- 并不要求如果两个对象根据equals(java.lang.Object)方法是不相等的,则对这两个对象中的每个对象调用hashCode方法必须产生不同的整数结果。然而,程序员应意识到,对于不相等的对象产生不同的整数结果可能会提高哈希表的性能。
英文:
Theoretically, it's possible to just implement equals
in RegionWithActivities
to make your test case pass as assertEquals
asserts based on equals()
of RegionWithActivities
. But implementing just equals()
and not implementing hashcode()
would violet Object class contract 2 as mentioned below -
> The general contract of hashCode is:
- Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
- If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
- It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论