c# NUnit单元测试没有使用正确的方法返回比较

本文关键字:方法 返回 比较 单元测试 NUnit | 更新日期: 2023-09-27 18:09:48

我有以下类

public static class MyClass
{
    public static double Converter(int mpg)
    {
       return Math.Round((double)mpg / ((double)36 / 12.74), 2);
    }
}

和NUnit单元测试

[TestFixture]
public class ConverterTests
{
    [Test]
    public void Basic_Tests()
        Assert.AreEqual(8.50, MyClass.Converter(24));
    }
}

使用

进行单元测试失败
Expected: 8.5d
But was:  8.4900000000000002d

当我调试方法返回8.49,那么单元测试从哪里得到长数字与2在结束?

c# NUnit单元测试没有使用正确的方法返回比较

单元测试显示的结果与我在执行代码时看到的结果相同。下面是一个简短但完整的程序,使用DoubleConverter类显示检索到的确切的结果。

using System;
class Test
{
    static void Main()
    {
        double x = Convert(24);
        Console.WriteLine(DoubleConverter.ToExactString(x));
    }
    static double Convert(int mpg)
    {
        return Math.Round((double) mpg / ((double) 36 / 12.74), 2);
    }
}
结果:

8.4900000000000002131628207280300557613372802734375

使用计算器,我期望未四舍五入的结果是8.4933333——当四舍五入到小数点后两位时,它确实是"大约8.49"。

所以实际上,问题更多的是为什么你在调试器中看到8.5,而不是为什么单元测试失败。我自己并没有看到这一点,所以您可能需要查看一下您是如何调试的。在调试时,您可能会看到不同的结果,因为:

  • 在调试中,你可能会使用不同的浮点运算,例如:"纯" 64位而不是。net
  • 允许的80位中间操作
  • 您可能正在调试其他将处理器的浮点模式设置为32位的代码;我在使用DirectX时看到过这种情况,但我希望你能意识到你正在做
  • 调试器可以以截断的形式显示结果,尽管我不希望它将该数字截断为8.5

'double'是一个肮脏的技巧来操作分数…: -)

永远不要在讨论双精度体时测试相等性。

正确的测试方法是:

Math.Abs(8.50 - MyClass.Converter(24)) <宽容>

其中"公差"是可接受的偏差的大小。

for TOLERANCE == 0.001
8.5004 == 8.50
8.4995 == 8.50
for TOLERANCE == 0.01
8.504 == 8.50
8.495 == 8.50