C#Fluent断言ShouldBeEquivalentTo的全局选项

时间:2013-12-19 23:45:27

标签: c# fluent-assertions

在Fluent Assertions中,将对象与DateTime属性进行比较时,有时会在毫秒内出现轻微的不匹配,并且比较失败。我们解决它的方法是设置比较选项,如下所示:

actual.ShouldBeEquivalentTo(expected,
        options =>
            options.Using<DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation))
                .WhenTypeIs<DateTime>());

有没有办法设置一次并让它始终适用,而不是每次调用ShouldBeEquivalentTo时都必须指定它?

UPDATE1: 尝试了以下方法,但它似乎不起作用,测试失败1毫秒的差异。工厂似乎没有调用新的默认值。

using System;
using FluentAssertions;
using FluentAssertions.Equivalency;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnitTestProject1
{
    class Test
    {
        public DateTime TestDateTime { get; set; }
    }

    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void SettingFluentAssertionDefault()
        {
            // arrange
            var defaultAssertionOptions = EquivalencyAssertionOptions<DateTime>.Default;

            EquivalencyAssertionOptions<DateTime>.Default = () =>
            {
                var config = defaultAssertionOptions();
                config.Using<DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation)).WhenTypeIs<DateTime>();
                return config;
            };

            var testDateTime = DateTime.Now;
            var expected = new Test {TestDateTime = testDateTime};

            // act
            var actual = new Test {TestDateTime = testDateTime.AddMilliseconds(1)};

            // assert
            actual.ShouldBeEquivalentTo(expected);
        }
    }
}

3 个答案:

答案 0 :(得分:17)

现在可以使用AssertionOptions静态类完成此操作。使用一个简单的例子:

[TestInitialize]
public void TestInit() {
  AssertionOptions.AssertEquivalencyUsing(options => options.ExcludingMissingMembers());
}

或者如上例所示:

AssertionOptions.AssertEquivalencyUsing(options =>
  options.Using<DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation)).WhenTypeIs<DateTime>()
);

答案 1 :(得分:12)

实际上,你可以。 static属性EquivalencyAssertionOptions<Test>.Default公开了默认配置工厂。您可以轻松地为特定数据类型分配备用配置,或使用其他行为扩展默认配置。类似的东西:

var defaultAssertionOptions = EquivalencyAssertionOptions<Test>.Default;

EquivalencyAssertionOptions<Test>.Default = () =>
{
    var config = defaultAssertionOptions();
    config.Using<DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation)).WhenTypeIs<DateTime>();
    return config;
};

如果你想要的话,你可以获得当前的默认值并将其隐藏在你从工厂方法中使用的某个变量中。

答案 2 :(得分:0)

我担心你最接近的是提供新方法

public static void ShouldBeEquivalentToDef<T>(this T subject, object expectation, string reason = "",
    params object[] reasonArgs)
{
    ShouldBeEquivalentToDef(subject, expectation, config => config, reason, reasonArgs);
}

public static void ShouldBeEquivalentToDef<T>(this T subject, object expectation,
    Func<EquivalencyAssertionOptions<T>, EquivalencyAssertionOptions<T>> config, string reason = "", params object[] reasonArgs)
{
    var context = new EquivalencyValidationContext
    {
        Subject = subject,
        Expectation = expectation,
        CompileTimeType = typeof (T),
        Reason = reason,
        ReasonArgs = reasonArgs
    };

    var defConstructedOptions = config(EquivalencyAssertionOptions<T>.Default());
    defConstructedOptions.Using<DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation))
            .WhenTypeIs<DateTime>()

    new EquivalencyValidator(defConstructedOptions).AssertEquality(context);
}