You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 18:35:27