JUnit测试GenericSet时union与intersection方法测试失败求助
JUnit测试失败问题修复
问题现象
- testUnion():打印显示预期结果
set3与实际返回结果set4内容一致,但assertEquals(set3, set4)和assertTrue(set3 == set4)均不通过 - testIntersection():返回结果
set4为空,因为GenericSet.java中retval.add(element)代码从未执行,无法通过if判断
问题原因
testUnion()失败根源:
==运算符比较的是对象内存地址,set3和set4是两个独立创建的对象,内存地址不同,因此assertTrue(set3 == set4)必然失败assertEquals默认调用对象的equals()方法,而GenericSet未重写Object类的equals(),默认仍比较内存地址,导致断言失败
testIntersection()失败根源:
- 测试用例中
set1为{1,2},set2因add()方法自动去重实际为{3},两者无交集,因此set.contains(element)始终返回false,不会执行retval.add(element) - 测试用例的预期结果
set3设置为{1,2,3},这本身不符合交集的定义,属于测试数据错误
- 测试用例中
修复方案
1. 重写GenericSet的equals()和hashCode()方法
让assertEquals能基于集合内容而非内存地址进行比较,必须重写这两个方法,以内部list的内容作为比较依据。
2. 修正testIntersection()测试用例
调整测试数据,使set1和set2存在交集,并将预期结果set3改为正确的交集内容。
修改后的代码
GenericSet.java
import java.util.ArrayList; import java.util.Objects; public class GenericSet<T> { ArrayList<T> list = new ArrayList<>(); public boolean add(T element) { if (list.contains(element)) { return false; } list.add(element); return true; } public boolean contains(T element) { for (T item : list) { if (item.equals(element)) { return true; } } return false; } public int size() { return list.size(); } public GenericSet<T> union(GenericSet<T> set) { GenericSet<T> retval = new GenericSet<>(); for (T element : this.list) { retval.add(element); } for (T element : set.list) { retval.add(element); } return retval; } public GenericSet<T> intersection(GenericSet<T> set) { GenericSet<T> retval = new GenericSet<>(); for (T element : this.list) { if (set.contains(element)) { retval.add(element); } } return retval; } public String toList() { StringBuilder builder = new StringBuilder(); for (T element : list) { builder.append(element).append(", "); } if (!list.isEmpty()) { builder.delete(builder.length() - 2, builder.length()); } return builder.toString(); } // 重写equals方法,基于内部list内容比较 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; GenericSet<?> that = (GenericSet<?>) o; return Objects.equals(list, that.list); } // 重写hashCode方法,与equals保持一致 @Override public int hashCode() { return Objects.hash(list); } }
GenericSetTest.java(仅修正testIntersection方法)
import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; class GenericSetTest { @Test void testAdd() { GenericSet<Integer> set1 = new GenericSet<>(); assertTrue(set1.add(1)); } @Test void testContains() { GenericSet<Integer> set = new GenericSet<>(); set.add(1); assertEquals(true, set.contains(1)); assertTrue(set.contains(1)); assertFalse(set.contains(3)); } @Test void testSize() { GenericSet<Integer> set = new GenericSet<>(); assertTrue(set.size() == 0); set.add(1); assertTrue(set.size() == 1); set.add(4); assertTrue(set.size() == 2); } @Test void testUnion() { GenericSet<Integer> set1 = new GenericSet<>(); GenericSet<Integer> set2 = new GenericSet<>(); GenericSet<Integer> set3 = new GenericSet<>(); set1.add(1); set1.add(2); set1.add(3); set2.add(3); set2.add(4); set3.add(1); set3.add(2); set3.add(3); set3.add(4); GenericSet<Integer> set4 = set1.union(set2); System.out.println("testUnion:"); System.out.println("set1: " + set1.toList()); System.out.println("set2: " + set2.toList()); System.out.println("set3: " + set3.toList()); System.out.println("set4: " + set4.toList()); System.out.println(); assertEquals(set3, set4); } @Test void testIntersection() { GenericSet<Integer> set1 = new GenericSet<>(); GenericSet<Integer> set2 = new GenericSet<>(); GenericSet<Integer> set3 = new GenericSet<>(); // set1 = {1, 2, 3} set1.add(1); set1.add(2); set1.add(3); // set2 = {3, 4} set2.add(3); set2.add(4); // 正确交集应为{3} set3.add(3); GenericSet<Integer> set4 = set1.intersection(set2); System.out.println("testIntersection:"); System.out.println("set1: " + set1.toList()); System.out.println("set2: " + set2.toList()); System.out.println("set3: " + set3.toList()); System.out.println("set4: " + set4.toList()); System.out.println(); assertEquals(set3, set4); } }
内容的提问来源于stack exchange,提问作者xampL
相关产品推荐
相关产品推荐

