提问人:ProtonFisher 提问时间:4/5/2023 更新时间:4/6/2023 访问量:87
FluentAssertions:自定义双比较器
FluentAssertions: Custom Double Comparer
问:
我尝试开始使用 FluentAssertions,但很快我就遇到了问题。我将它与 MSTest 一起使用。下面的测试失败了不应该发生的事情(从我的角度来看)。
[TestMethod]
public void DoubleTest()
{
double temp1 = 0.1 - 0.025;
double temp2 = 0.075;
temp1.ShouldBeEquivalentTo(temp2, options => options.Using<double>
(a => a.Subject.HasMinimalDifference(a.Expectation, 1)).WhenTypeIs<double>());
}
public static bool HasMinimalDifference(double value1, double value2, int units)
{
long lValue1 = BitConverter.DoubleToInt64Bits(value1);
long lValue2 = BitConverter.DoubleToInt64Bits(value2);
// If the signs are different, return false except for +0 and -0.
if ((lValue1 >> 63) != (lValue2 >> 63))
{
if (value1 == value2)
return true;
return false;
}
long diff = Math.Abs(lValue1 - lValue2);
if (diff <= (long) units)
return true;
return false;
}
我做了相当多的研究,但我的印象是 Fluent Assertions 忽略了自定义的双比较器。还是只有我?我真的很想使用自定义的双比较器,因为将来可能会通过上面的 MS 示例进行扩展。 任何帮助将不胜感激。
答:
0赞
Jonas Nyrup
4/5/2023
#1
这里似乎正在发生两件事。
1) 期望执行断言的操作。Using
Using<TProperty>(Action<IAssertionContext<TProperty>> action)
您可以使用 解决此问题。HasMinimalDifference(a.Subject, a.Expectation, 1).Should().BeTrue()
2)
由于您正在使用,因此您必须运行 v4.19.4 或更早版本,因为我们在 v5 中删除了该方法。ShouldBeEquivalentTo
我可以在 v4.19.4 中重现该错误。
您遇到了一个错误,其中未对根对象应用自定义断言。 该错误已在 https://github.com/fluentassertions/fluentassertions/pull/1033 中修复,并作为 v5.7.0 的一部分发布。
[TestMethod]
public void DoubleTest()
{
object temp1 = 0.1 - 0.025;
object temp2 = 0.075;
temp1.Should().BeEquivalentTo(temp2, options => options
.Using<double>(a => HasMinimalDifference(a.Subject, a.Expectation, 1).Should().BeTrue())
.WhenTypeIs<double>());
}
public static bool HasMinimalDifference(double value1, double value2, int units)
{
long lValue1 = BitConverter.DoubleToInt64Bits(value1);
long lValue2 = BitConverter.DoubleToInt64Bits(value2);
// If the signs are different, return false except for +0 and -0.
if ((lValue1 >> 63) != (lValue2 >> 63))
{
if (value1 == value2)
return true;
return false;
}
long diff = Math.Abs(lValue1 - lValue2);
if (diff <= (long)units)
return true;
return false;
}
我还没有研究过什么计算,但这里有一种惯用的方法,可以对所有双打进行轻松的比较。文档HasMinimalDifference
[TestMethod]
public void DoubleTest()
{
object temp1 = 0.1 - 0.025;
object temp2 = 0.075;
temp1.Should().BeEquivalentTo(temp2, options => options
.Using<double>(a => a.Subject.Should().BeApproximately(a.Expectation, 1))
.WhenTypeIs<double>());
}
评论
1赞
ProtonFisher
4/5/2023
嘿@Jonas,非常感谢,这解决了它,并有助于更好地了解在这种情况下发生了什么!
0赞
ProtonFisher
4/6/2023
嘿,乔纳斯,只是一个简短的跟进:我试图避免使用“BeApprox”,因为我不确定在通用情况下应该输入什么作为精度。“HasMinimalDifference”比较最后一个有效位,因此两个双精度之间的差异可以约为这 16 个数量级。'双倍。Epsilon' 作为精度将无法通过测试,因为它很小。Смотритетакже: C# 走向数学
评论