17

在 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);
        }
    }
}
4

3 回答 3

23

现在这可以通过 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>()
);
于 2015-03-19T23:04:51.333 回答
18

事实上,你可以。默认配置工厂由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;
};

如果您愿意,您可以获取当前默认值并将其隐藏在您从工厂方法中使用的某个变量中。

于 2013-12-20T12:06:50.413 回答
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);
}
于 2013-12-20T00:56:56.220 回答