Java Assert.assertEquals在两个列表上
我在我的学校有一门课:Java Assert.assertEquals在两个列表上,java,junit,junit4,junit3,Java,Junit,Junit4,Junit3,我在我的学校有一门课: public class MySchool{ private long timestamp; private SchoolEvent event; private Object value; //getter & setters ... @Override public String toString() { return "MySchool [timestamp=" + timestam
public class MySchool{
private long timestamp;
private SchoolEvent event;
private Object value;
//getter & setters
...
@Override
public String toString() {
return "MySchool [timestamp=" + timestamp + ", event="
+ event + ", value=" + value + "]";
}
}
SchoolEvent
是枚举类型:
public static enum SchoolEvent {
CEREMONY, HOLIDAY
}
我试着用它来比较两个学校列表:
List<MySchool> schoolList1 = generateSchools();
List<MySchool> schoolList2 = readSchoolsFromFile();
Assert.assertEquals(schoolList1, schoolList2);
List schoolList1=generateSchools();
List schoolList2=readSchoolsFromFile();
Assert.assertEquals(学校列表1、学校列表2);
失败,出现以下错误:
expected: java.util.ArrayList<[MySchool [timestamp=0, event=CEREMONY, value=null], MySchool [timestamp=0, event=HOLIDAY, value=null]]>
but was: java.util.ArrayList<[MySchool [timestamp=0, event=CEREMONY, value=null], MySchool [timestamp=0, event=HOLIDAY, value=null]]>
应为:java.util.ArrayList
但是是:java.util.ArrayList
我不明白为什么这个错误听起来不像一个错误,我的意思是检查错误消息,两个列表中每个元素对象的每个字段都是Eqal
我还检查了Java文档,它还说:
如果两个列表包含相同的元素,则它们被定义为相等
按同样的顺序
那么为什么assertEquals()失败了呢
我不明白为什么这个错误听起来不像一个错误,我的意思是检查错误消息,两个列表中每个元素对象的每个字段都是Eqal
是的,但这并不意味着物体是相等的
您需要重写equals()
(和hashCode()
)才能将不同的对象视为相等。默认情况下,equals
方法只检查对象标识。。。换句话说,x.equals(y)
相当于检查默认情况下x
和y
引用的对象是否完全相同。如果您想要不同的行为-以便检查某些字段是否相等-那么您需要在equals()
中指定该行为,并以与之一致的方式实现hashCode()
请注意,这个问题根本不依赖于集合。如果比较单个对象,也会遇到同样的问题:
MySchool school1 = schoolList1.get(0);
MySchool school2 = schoolList2.get(0);
Assert.areEqual(school1, school2); // This will fail...
我不明白为什么这个错误听起来不像一个错误,我的意思是检查错误消息,两个列表中每个元素对象的每个字段都是Eqal
是的,但这并不意味着物体是相等的
您需要重写equals()
(和hashCode()
)才能将不同的对象视为相等。默认情况下,equals
方法只检查对象标识。。。换句话说,x.equals(y)
相当于检查默认情况下x
和y
引用的对象是否完全相同。如果您想要不同的行为-以便检查某些字段是否相等-那么您需要在equals()
中指定该行为,并以与之一致的方式实现hashCode()
请注意,这个问题根本不依赖于集合。如果比较单个对象,也会遇到同样的问题:
MySchool school1 = schoolList1.get(0);
MySchool school2 = schoolList2.get(0);
Assert.areEqual(school1, school2); // This will fail...
要使两个对象相等,其
equals()
方法必须返回true
equals()的默认实现仅在两个对象是同一对象时返回true,但在它们是具有相同“内容”的不同对象时不返回true
所以,
x等于(y)
可以是true
,即使x==y
(“x和y是同一个对象”)是false
,如果x方法的equals()
为参数y返回true
。对于要相等的两个对象,其equals()
方法必须返回true
equals()的默认实现仅在两个对象是同一对象时返回true,但在它们是具有相同“内容”的不同对象时不返回true
所以,
x等于(y)
可以是true
,即使x==y
(“x和y是同一个对象”)是false
,如果x方法的equals()
为参数y返回true
。类必须实现equals()。我将在下面添加一个示例实现:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MySchool mySchool = (MySchool) o;
if (timestamp != mySchool.timestamp) return false;
if (event != mySchool.event) return false;
return !(value != null ? !value.equals(mySchool.value) : mySchool.value != null);
}
然后我将使用hamcrest对集合进行断言:
public void testTwoEventsAreEquals() throws Exception {
List<MySchool> schoolList1 = Arrays.asList(new MySchool(SchoolEvent.CEREMONY), new MySchool(SchoolEvent.HOLIDAY));
List<MySchool> schoolList2 = Arrays.asList(new MySchool(SchoolEvent.CEREMONY), new MySchool(SchoolEvent.HOLIDAY));
assertThat(schoolList1, containsInAnyOrder(schoolList2.toArray()));
}
public void testtwoEventsReequals()引发异常{
listschoollist1=Arrays.asList(newmyschool(schooleevent.receive)、newmyschool(schooleevent.HOLIDAY));
listschoollist2=Arrays.asList(newmyschool(schooleevent.receive)、newmyschool(schooleevent.HOLIDAY));
资产(学校列表1,包含任何订单(学校列表2.toArray());
}
如果您使用的是maven,则必须添加Hamcrest作为依赖项,以便编译上述代码
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
</dependency>
org.hamcrest
汉克雷斯特酒店
1.3
您的类必须实现equals()。我将在下面添加一个示例实现:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MySchool mySchool = (MySchool) o;
if (timestamp != mySchool.timestamp) return false;
if (event != mySchool.event) return false;
return !(value != null ? !value.equals(mySchool.value) : mySchool.value != null);
}
然后我将使用hamcrest对集合进行断言:
public void testTwoEventsAreEquals() throws Exception {
List<MySchool> schoolList1 = Arrays.asList(new MySchool(SchoolEvent.CEREMONY), new MySchool(SchoolEvent.HOLIDAY));
List<MySchool> schoolList2 = Arrays.asList(new MySchool(SchoolEvent.CEREMONY), new MySchool(SchoolEvent.HOLIDAY));
assertThat(schoolList1, containsInAnyOrder(schoolList2.toArray()));
}
public void testtwoEventsReequals()引发异常{
listschoollist1=Arrays.asList(newmyschool(schooleevent.receive)、newmyschool(schooleevent.HOLIDAY));
listschoollist2=Arrays.asList(newmyschool(schooleevent.receive)、newmyschool(schooleevent.HOLIDAY));
资产(学校列表1,包含任何订单(学校列表2.toArray());
}
如果您使用的是maven,则必须添加Hamcrest作为依赖项,以便编译上述代码
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
</dependency>
org.hamcrest
汉克雷斯特酒店
1.3
不要像其他人(对不起,伙计们)建议的那样使用等于
的方法。这将是生产中的一个测试代码,它不仅本身是错误的,而且如果您在类中添加了另一个字段,但忘记了更新equals
方法会怎么样?你的测试不会测试你认为他们正在测试的东西。如果equals
方法是错误的呢?如果它总是返回true呢?你的测试总是绿色的,你会错误地相信一切都很好。当然,因为谁会为方法编写一个测试
我强烈建议使用以下工具:。这允许您只编写资产(实际的,sameBeanAs(预期的))
,而不必担心任何事情。它不需要对生产代码进行任何更改。它将覆盖所有字段,而不考虑其访问修饰符。也提供了非常好的诊断。它抛出comparisonfail
(而不是