提供 FluentAssertions 的扩展

Posted

技术标签:

【中文标题】提供 FluentAssertions 的扩展【英文标题】:Providing an extension to FluentAssertions 【发布时间】:2021-05-27 05:45:39 【问题描述】:

因为我有一些角度,所以我想检查一个角度模数 360°:

    double angle = 0;
    double expectedAngle = 360;
    angle.Should().BeApproximatelyModulus360(expectedAngle, 0.01);

我已经为 Fluent Assertions 框架编写了一个扩展 跟随教程:https://fluentassertions.com/extensibility/

public static class DoubleExtensions

  public static DoubleAssertions Should(this double d)
  
    return new DoubleAssertions(d);
  



public class DoubleAssertions : NumericAssertions<double>

  public DoubleAssertions(double d) : base(d)
  
  
  public AndConstraint<DoubleAssertions> BeApproximatelyModulus360(
      double targetValue, double precision, string because = "", params object[] becauseArgs)
  
    Execute.Assertion
        .Given(() => Subject)
        .ForCondition(v => MathHelper.AreCloseEnoughModulus360(targetValue, (double)v, precision))
        .FailWith($"Expected value Subject] should be approximatively targetValue with precision modulus 360");
    return new AndConstraint<DoubleAssertions>(this);

当我同时使用两个命名空间时:

using FluentAssertions;
using MyProjectAssertions;

因为我也用:

 aDouble.Should().BeApproximately(1, 0.001);

我得到以下编译错误: Ambiguous call between 'FluentAssertions.AssertionExtensions.Should(double)' and 'MyProjectAssertions.DoubleExtensions.Should(double)'

如何更改我的代码以扩展标准 NumericAssertions(或其他合适的类)以将我的 BeApproximatelyModulus360 放在标准 BeApproximately 旁边?

谢谢

【问题讨论】:

删除其中一个命名空间的using... 语句或直接调用方法MyProjectAssertions.DoubleExtensions.Should(yourDouble) 当然!你说得对。但我期待一种更短的写作方式。因为它使我的调用像 FluentAssertions.DoubleExtensions.Should(luminanceComputation.Beta).BeApproximatelyModulus360(0,0.01); - 与:Assert.True(MathHelper.AreCloseEnoughModulus360(0,luminanceComputation.Beta,0.01))进行比较; - 这已经不是很流利了。 实际上还有一些我刚刚遇到的其他命名冲突阻止了使用我的新断言 Api 标准 FluentAssertion 一 【参考方案1】:

如果您想直接访问double 对象上的扩展方法,而不是DoubleAssertion 对象上的扩展方法,为什么还要引入甚至创建新类型DoubleAssertion 的复杂性。而是直接为NumericAssertions&lt;double&gt; 定义扩展方法。

  public static class DoubleAssertionsExtensions
    
        public static AndConstraint<NumericAssertions<double>> BeApproximatelyModulus360(this NumericAssertions<double> parent,
            double targetValue, double precision, string because = "", params object[] becauseArgs)
        
            Execute.Assertion
                .Given(() => parent.Subject)
                .ForCondition(v => MathHelper.AreCloseEnoughModulus360(targetValue, (double)v, precision))
                .FailWith(
                    $"Expected value parent.Subject] should be approximatively targetValue with precision modulus 360");
            return new AndConstraint<NumericAssertions<double>>(parent);
        
    

然后你可以一起使用它们。

 public class Test
    
        public Test()
        
            double aDouble = 4;

            aDouble.Should().BeApproximately(1, 0.001);
            aDouble.Should().BeApproximatelyModulus360(0, 0.1);

        
    

【讨论】:

非常感谢 Marshal,您帮我找回了丢失的清晰度

以上是关于提供 FluentAssertions 的扩展的主要内容,如果未能解决你的问题,请参考以下文章

在 FluentAssertions.Primitives.ObjectAssertions 的扩展方法中调用 Excluding 方法不起作用,但调用它正常工作

VS/xUnit/FluentAssertions:在测试消息中提供文件链接

FluentAssertions:排序列表的等价性

FluentAssertions 是不是支持字典的 WithStrictOrdering?

FluentAssertions 不应该包含失败

FluentAssertions:int.Should().Equals 返回错误的结果?