JUnit断言错误:预期与实际输出一致仍报错问题排查
JUnit断言错误排查:内容显示一致却报错AssertionFailedError
问题场景
在线技术测评时碰到JUnit断言错误,明明预期输出和实际输出的内容看起来完全一样,却抛出org.opentest4j.AssertionFailedError。测试用例是别人写的,不清楚具体实现逻辑。
报错信息
org.opentest4j.AssertionFailedError: expected: java.util.ArrayList@2bbf180e<[[1, 2, 3], [4, 5, 6]]> but was: java.util.ArrayList@163e4e87<[[1, 2, 3], [4, 5, 6]]> at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55) at org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62) at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182) at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:177) at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1141) at parseCsvTest$ExampleTests.shouldHandleSimpleInputs(parseCsvTest.java:17) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725) at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
我的实现代码
public class Challenge { public static ArrayList<ArrayList<String>> parseCsv( String csv, String separator, String quote ) { String[] splitted = csv.split("\n"); ArrayList<ArrayList<String>> result = new ArrayList<>(); for (int i = 0; i< splitted.length; i++) { String[] st = splitted[i].split(separator); String string = new String(); for (int j = 0; j < st.length; j++) { string += st[j]; if (j != st.length - 1) { string += ", "; } } ArrayList<String> temp = new ArrayList<>(); temp.add(string); result.add(temp); } return result; }
问题原因与修复方案
核心问题
报错里的对象地址不同(@2bbf180e和@163e4e87)不是关键——JUnit的assertEquals对集合是比较内容而非对象引用。真正的问题是返回结构和预期不匹配:
- 预期结构:外层ArrayList包含两个子ArrayList,每个子列表有3个独立元素:
[[1,2,3], [4,5,6]] - 你的实现结构:外层ArrayList包含两个子ArrayList,每个子列表只有1个拼接后的字符串元素:
[["1, 2, 3"], ["4, 5, 6"]]
修复后的代码
public class Challenge { public static ArrayList<ArrayList<String>> parseCsv( String csv, String separator, String quote ) { String[] splitted = csv.split("\n"); ArrayList<ArrayList<String>> result = new ArrayList<>(); for (String line : splitted) { String[] elements = line.split(separator); ArrayList<String> temp = new ArrayList<>(); // 直接将拆分后的每个元素添加到子列表,不要拼接成单个字符串 for (String element : elements) { temp.add(element); } // 也可以用更简洁的写法: // ArrayList<String> temp = new ArrayList<>(Arrays.asList(elements)); result.add(temp); } return result; } }
额外说明
如果测试用例后续包含带引号的CSV字段(比如"a,b",c),当前的split(separator)会错误拆分引号内的分隔符,这时候需要更复杂的逻辑来识别引号包裹的内容。但针对当前报错的测试用例,上面的修复足以解决问题。
内容的提问来源于stack exchange,提问作者roshan1892
相关产品推荐
相关产品推荐

