如何在C#单元测试中对decimal类型使用Assert.Equal()解决类型匹配报错
问题解答
你遇到的报错核心原因不是Assert.Equal处理decimal的特殊规则,而是类型不匹配+多余的类型转换导致精度丢失:
Message: Assert.AreEqual failed. Expected:<0.2690288718 (System.Decimal)>. Actual:<0.26902887 (System.String)>
问题根因
- 类型不匹配:你的测试代码中调用了
ConvertDecimalToString方法,把转换接口返回的decimal结果转成了字符串类型的actualResult,但你拿来和decimal类型的expectedResult做相等断言,二者类型不一致必然会校验失败。 - 精度截断:从你贴的
ConvertStringToDecimal逻辑可以推断,ConvertDecimalToString会把decimal值格式化为仅保留8位小数的字符串,你的预期计算结果0.082 * 3.2808399 = 0.2690288718,转字符串后会被截断为0.26902887,就算后续转回decimal也和原始预期值的精度不一致。 - 额外注意:你当前贴出的
LinearWeightUnitConvert代码仅实现了fromUnit为KG/M的转换分支,你测试用的输入单位kg/ft没有对应的处理逻辑,需要先补全该分支的转换规则,否则接口会返回默认值0。
正确测试写法
场景1:仅测试单位转换核心逻辑LinearWeightUnitConvert
直接接收接口返回的decimal值,不要做多余的字符串转换,decimal的Assert.AreEqual默认支持精确比较,如果你需要允许业务范围内的精度误差,可以传入第三个参数指定允许的最大差值:
[TestMethod] public void ValidateConversionKG_FTtoKG_M() { decimal actualValuetoConvert = 0.082M; string actualFromUnit = "kg/ft"; string actualToUnit = "kg/m"; // 直接拿转换返回的decimal结果,不要转字符串 decimal actualResult = ESPv2MigrationTool.CommonTools.Conversion.LinearWeightUnitConvert(actualValuetoConvert, actualFromUnit, actualToUnit); decimal expectedResult = actualValuetoConvert * 3.2808399M; // 示例:允许误差为小数点后8位,可根据业务需求调整 Assert.AreEqual(expectedResult, actualResult, 0.00000001M); }
场景2:测试包含字符串转换的完整流程ConvertValueOfLinearWeight
如果需要验证包含格式化输出的全链路逻辑,就把预期值也按照同样的规则转成字符串再做比较:
[TestMethod] public void ValidateConversionKG_FTtoKG_M_FullFlow() { decimal actualValuetoConvert = 0.082M; string actualFromUnit = "kg/ft"; string actualToUnit = "kg/m"; string actualResult = ESPv2MigrationTool.CommonTools.Utils.ConvertDecimalToString(ESPv2MigrationTool.CommonTools.Conversion.LinearWeightUnitConvert(actualValuetoConvert, actualFromUnit, actualToUnit)); // 预期值也按照相同规则格式化后再比较 decimal expectedDecimal = actualValuetoConvert * 3.2808399M; string expectedResult = expectedDecimal.ToString("#0.########", CultureInfo.InvariantCulture); Assert.AreEqual(expectedResult, actualResult); }
decimal类型断言的注意事项
- 默认是精确比较,包括小数位数,
0.2690288718M和0.26902887M会被判定为不相等 - 若业务允许一定精度误差,可给
Assert.AreEqual传入第三个参数指定允许的最大差值,例如要保留8位小数就传0.00000001M - 禁止跨类型比较,确保断言的两个值同为decimal类型,或者同为相同规则格式化后的字符串类型
内容的提问来源于stack exchange,提问作者RRuseva
相关产品推荐
相关产品推荐

