FluentAssertions 当类型为 double.NaN 时

3

我有两个复杂对象,内部包含不同类型(对象、字符串、双精度浮点数等)。我想使用以下代码比较它们:

myActualObject.ShouldBeEquivalentTo(myExpectedObject, options => options
        .Using<double>(dbl => dbl.Subject.Should().BeApproximately(dbl.Expectation,
         ABS_ERROR))
        .WhenTypeIs<double>()
    );

我正在尝试使用.BeApproximately行为来比较double类型属性值,但是由于一个特殊情况,它不起作用:
  • 有时我在double中有一个double.NaN,将NaN与另一个NaN进行比较会导致断言失败(因为BeApproximately行为)。如何跳过比较或使其在这种情况下为真?

  • 最后,我如何打印导致断言失败的对象名称?

预先感谢。

编辑>>>>

我已经找到了第一种方法(感谢@Sam Holder):

myActualObject.ShouldBeEquivalentTo(myExpectedObject, options => options
        .Using<double>(ctx => CompareDoubleApprox(ctx, myExpectedObject.Name))
        .WhenTypeIs<double>()
);

...

public void CompareDoubleApprox(IAssertionContext<double> ctx, string Scope)
{
    bool IsDoubleOrInfinite = (double.IsNaN(ctx.Expectation) || double.IsInfinity(ctx.Expectation));
    bool absoluteErrorOK = Math.Abs(ctx.Subject - ctx.Expectation) < ABS_ERROR;

    Execute.Assertion
         .BecauseOf(ctx.Reason, ctx.ReasonArgs)
         .ForCondition(IsDoubleOrInfinite || absoluteErrorOK)
         .FailWith("{3}: Expected {context:double} to be {0} +/- {1} {reason}, but found {2}", ctx.Subject, ABS_ERROR, ctx.Expectation, Scope);
}

我的断言转储看起来像:

"MyObjectName":预期成员Foo.Bar为0 +/- 1E-05, 但发现1,39675

"MyObjectName":预期成员Foo.FooBar为2,07781 +/- 1E-05, 但发现2,98412

...更多的断言失败...

我希望它在打印所有失败之前只打印一次对象名称。

更新>>>>

我想要的行为尚未在github上实现:https://github.com/dennisdoomen/fluentassertions/issues/310。被标记为增强功能。感谢您的帮助。

1个回答

3
未经测试的猜测,但可能会像这样工作:
myActualObject.ShouldBeEquivalentTo(myExpectedObject, options => options
    .Using<double>(dbl =>
       { 
           if (!double.IsNaN(dbl.Subject))
           {
               String errorMessage = string.Format("{0} caused the assertion to fail",myExpectedObject);
               dbl.Subject.Should().BeApproximately(dbl.Expectation, ABS_ERROR, errorMessage);
           }
       })
    .WhenTypeIs<double>()
);

它运行了!现在只需要知道如何打印导致断言失败的对象的名称。 - Jose
这取决于您使用的测试运行程序。您是如何运行测试的?尝试将其切换为“Console.WriteLine”。 - Sam Holder
我希望它能在与断言相同的范围内打印,就像系统一样:Assert.IsNotNull(myActualObject, "myActualObjec is null"); - Jose
ABS_ERROR是一个双精度浮点数(在这种情况下为0.00001),用于比较大小。它与对象名称无关。 - Jose
它还没有被实现(https://github.com/dennisdoomen/fluentassertions/issues/310)。我会将这个答案标记为有效的,感谢您的帮助。 - Jose
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接