C#单元测试未通过:GetSerialNumberDetails方法索引越界问题排查
C# GetSerialNumberDetails方法异常排查与修正
问题背景
需要实现GetSerialNumberDetails方法,从序列号中提取国家码、制造商码、工厂码和工位码,满足以下测试用例:
[TestCase("P2W12P1937A", "W", "12", "1937", "A")] [TestCase("P02K13P8732D", "K", "13", "8732", "D")] [TestCase("P002Z14P3573B", "Z", "14", "3573", "B")]
提取规则:
- 国家码:字符“2”之后的第一个字符
- 制造商码:某个“P”之前的两位字符
- 工厂码:倒数第5到倒数第2位的字符
- 工位码:最后一位字符
当前代码执行测试时全部抛出System.IndexOutOfRangeException,需排查并修正。
当前代码的错误点
制造商码获取逻辑错误
当前使用serialNumber.IndexOf('P')获取第一个'P'的索引,而第一个'P'通常在字符串开头(索引0),减2后得到-2,直接导致索引越界。根据测试用例,制造商码是第二个'P'(即最后一个'P')前面的两位,比如第一个测试用例中,第二个'P'在索引5,其前两位是索引3、4的"12",正好匹配测试预期。工厂码范围运算符使用错误
C#的范围运算符[^5..^2]是左闭右开区间,会排除倒数第2位字符。测试用例需要的是倒数第5到倒数第2位(包含两端),因此该范围只能取到3个字符,不符合预期的4位工厂码。
修正后的代码
public static void GetSerialNumberDetails(string serialNumber, out string countryCode, out string manufacturerCode, out string factoryCode, out string stationCode) { ArgumentNullException.ThrowIfNull(serialNumber); // 获取国家码:找到最后一个'2'的位置,取其后一位字符 int lastTwoIndex = serialNumber.LastIndexOf('2'); countryCode = serialNumber[lastTwoIndex + 1].ToString(); // 获取制造商码:找到最后一个'P'的位置,取其前两位字符 int lastPIndex = serialNumber.LastIndexOf('P'); manufacturerCode = serialNumber.Substring(lastPIndex - 2, 2); // 获取工厂码:从倒数第5位开始取4个字符(覆盖倒数第5到倒数第2位) factoryCode = serialNumber.Substring(serialNumber.Length - 5, 4); // 获取工位码:最后一位字符 stationCode = serialNumber[^1].ToString(); }
修正说明
- 国家码:改用
LastIndexOf('2')确保找到最右侧的'2'(适配测试用例中多个'2'的场景),取其后一位字符。 - 制造商码:用
LastIndexOf('P')找到最后一个'P',通过Substring截取其前两位,彻底避免索引越界问题。 - 工厂码:使用
Substring(serialNumber.Length -5, 4)直接从倒数第5位开始取4个字符,直观且完全匹配测试预期的4位工厂码。 - 工位码:原逻辑正确,保留使用索引
[^1]获取最后一位。
内容的提问来源于stack exchange,提问作者Aleksey
相关产品推荐
相关产品推荐

