You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用FluentAssertions比较DateOnly与DateTime类型?

问题描述

以下是简化后的测试代码:

record Type1(DateOnly Date);
record Type2(DateTime Date);

[Fact]
public void Whatever()
{
   var type1s = new[] { new Type1(DateOnly.Parse("2024-06-01")), new Type1(DateOnly.Parse("2024-07-01")) };
   var type2s = new[] { new Type2(DateTime.Parse("2024-06-01")), new Type2(DateTime.Parse("2024-07-01")) };

   type1s.Should().BeEquivalentTo(type2s);
}

执行测试后失败,报错信息如下:

期望属性type1s[0].Date的值为<2024-06-01>,但实际为<2024-06-01>。
期望属性type1s[1].Date的值为<2024-07-01>,但实际为<2024-07-01>。

需要配置FluentAssertions使其能正确比较DateTime与DateOnly类型。

解决方案

方法1:局部等价性配置

在BeEquivalentTo方法中传入自定义配置,指定两种类型的转换比较规则:

type1s.Should().BeEquivalentTo(type2s, options => options
    // 当期望类型是DateTime、实际是DateOnly时,将DateTime转成DateOnly比较
    .Using<DateOnly>(ctx => ctx.Subject.Should().Be(DateOnly.FromDateTime(ctx.Expectation)))
    .WhenTypeIs<DateTime>()
    // 当期望类型是DateOnly、实际是DateTime时,将DateOnly转成DateTime(时间取最小)比较
    .Using<DateTime>(ctx => ctx.Subject.Should().Be(ctx.Expectation.ToDateTime(TimeOnly.MinValue)))
    .WhenTypeIs<DateOnly>());

方法2:全局配置(项目级生效)

如果多个测试需要统一的类型比较规则,可在测试项目初始化代码中注册全局配置:

FluentAssertions.AssertionOptions.AssertEquivalencyUsing(options => options
    .Using<DateOnly>(ctx => ctx.Subject.Should().Be(DateOnly.FromDateTime(ctx.Expectation)))
    .WhenTypeIs<DateTime>()
    .Using<DateTime>(ctx => ctx.Subject.Should().Be(ctx.Expectation.ToDateTime(TimeOnly.MinValue)))
    .WhenTypeIs<DateOnly>());

配置完成后,所有使用BeEquivalentTo的测试都会自动应用该转换规则。

方法3:自定义比较器

实现自定义相等比较器,再在配置中引用:

public class DateOnlyDateTimeComparer : IEqualityComparer
{
    public new bool Equals(object x, object y)
    {
        if (x is DateOnly dateOnly && y is DateTime dateTime)
        {
            return dateOnly.Equals(DateOnly.FromDateTime(dateTime));
        }
        if (x is DateTime dt && y is DateOnly do_)
        {
            return DateOnly.FromDateTime(dt).Equals(do_);
        }
        return EqualityComparer<object>.Default.Equals(x, y);
    }

    public int GetHashCode(object obj)
    {
        return obj?.GetHashCode() ?? 0;
    }
}

测试中使用该比较器:

type1s.Should().BeEquivalentTo(type2s, options => options
    .Using(new DateOnlyDateTimeComparer())
    .WhenTypeIs<DateOnly>()
    .Using(new DateOnlyDateTimeComparer())
    .WhenTypeIs<DateTime>());

内容的提问来源于stack exchange,提问作者mnj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 03:27:38