Java自定义字符串remove方法测试返回null报AssertionFailedError
问题现象
实现字符串指定字符移除功能时,单元测试执行后返回null,抛出AssertionFailedError断言失败错误。
相关代码
失败测试用例
assertEquals("", this.myCustomString.remove("")); this.myCustomString.setString(null); assertEquals("", this.myCustomString.remove("")); this.myCustomString.setString("my lucky numbers are 6, 8, and 19."); assertEquals("my lucky numbes e 6, 8, nd 19.", this.myCustomString.remove("ra6"));
原有问题实现
public String remove(String arg){//removes specified characters from the string if (myString == null || myString == "") { return this.myString; } if (myString != null) { this.myString = myString.replaceAll(arg,""); return myString; } return myString; }
逻辑缺陷排查
- 空分支返回值错误:当内部存储的
myString为null时,第一个判断分支直接返回null,和测试用例要求的空串返回值不符,这是测试返回null的直接原因。 - 字符串比较写法错误:用
==比较字符串内容是Java常见写法错误,==比较的是对象内存引用地址而非实际字符串内容,当myString是通过new创建的空串时,该判断不会命中,会触发后续意外逻辑。 - 核心移除逻辑不符合需求:
replaceAll(arg, "")的作用是按正则规则匹配连续的目标子串做替换,不是逐字符移除所有出现在参数里的单个字符。比如传入"ra6"时,原逻辑只会查找连续的r→a→6子串替换,不会分别删除所有r、a、6字符,结果必然不符合预期。 - 冗余无效代码:第一个分支已经拦截了
myString == null的场景,后续的if (myString != null)判断和末尾的return语句永远不会按预期触发,属于冗余代码。 - 边界场景缺失:没有处理入参
arg为null的场景,传入null时replaceAll会直接抛出空指针异常。
修复后实现
按需求逐字符移除目标字符,覆盖所有边界场景,可通过测试用例:
public String remove(String arg) { // 内部存储字符串为null或空时,统一返回空串,匹配前两个测试用例预期 if (myString == null || myString.isEmpty()) { return ""; } // 移除参数为null或空时,无需要移除的字符,直接返回当前字符串 if (arg == null || arg.isEmpty()) { return myString; } String result = myString; // 遍历参数中的每个字符,逐个移除字符串中所有匹配的字符 for (char c : arg.toCharArray()) { result = result.replace(String.valueOf(c), ""); } // 同步更新内部存储的字符串值 this.myString = result; return result; }
注:如果传入参数"ra6"时需要保留数字6,只需在字符遍历逻辑中增加数字字符跳过判断即可,当前实现严格遵循“移除参数中所有指定字符”的方法设计要求。
内容的提问来源于stack exchange,提问作者Andrew Croke
相关产品推荐
相关产品推荐

