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

如何用FluentAssertions的Contain结合BeCloseTo比较DateTimeOffset集合

问题:使用FluentAssertions检查集合中是否存在近似匹配的DateTimeOffset值

需求说明

需要将字符串解析为DateTimeOffset,并用FluentAssertions验证集合中是否存在该值;由于时间存在精度误差,需结合.BeCloseTo方法完成近似比较。已知CronExpressions包含Raw属性,可将其转换为DateTimeOffset。

尝试的测试代码

最初的实现写法:

[Test]
public void SchedulesItselfForNow()
{
    this.job = new Job();

    this.job.MetaData.CronExpressions.Should().Contain(x =>
        DateTimeOffset.Parse(x.Raw).Should().BeCloseTo(DateTimeOffset.Now, TimeSpan.FromMinutes(1))
    );
}

ChatGPT给出的重构方案

[Test]
public void SchedulesItselfForNow()
{
    this.job = new Job();

    this.job.MetaData.CronExpressions
        .Select(x => DateTimeOffset.Parse(x.Raw))
        .Should()
        .Contain(date => date.Should().BeCloseTo(DateTimeOffset.Now, TimeSpan.FromMinutes(1)));
}

疑问与尝试

希望使用.Which语法,但不清楚如何填充Contain的条件:

[Test]
public void SchedulesItselfForNow()
{
    this.job = new Job();

    this.job.MetaData.CronExpressions
        .Select(x => DateTimeOffset.Parse(x.Raw))
        .Should()
        .Contain(date => true) // 此处应使用什么条件?
        .Which.Should().BeCloseTo(DateTimeOffset.Now, TimeSpan.FromMinutes(1));
}

正确实现方式

Contain方法需要的是返回bool的谓词逻辑,而非直接在内部抛出断言异常。同时建议提前缓存基准时间,避免多次调用DateTimeOffset.Now导致的时间差干扰判断:

方式1:直接用布尔逻辑判断近似匹配

[Test]
public void SchedulesItselfForNow()
{
    this.job = new Job();
    var currentTime = DateTimeOffset.Now;
    var timeTolerance = TimeSpan.FromMinutes(1);

    this.job.MetaData.CronExpressions
        .Select(x => DateTimeOffset.Parse(x.Raw))
        .Should()
        .Contain(date => Math.Abs((date - currentTime).TotalMilliseconds) <= timeTolerance.TotalMilliseconds);
}

方式2:结合.Which完成链式断言

如果需要后续对匹配到的项做更多断言,可以先通过布尔谓词找到目标项,再用.Which接续验证:

[Test]
public void SchedulesItselfForNow()
{
    this.job = new Job();
    var currentTime = DateTimeOffset.Now;
    var timeTolerance = TimeSpan.FromMinutes(1);

    this.job.MetaData.CronExpressions
        .Select(x => DateTimeOffset.Parse(x.Raw))
        .Should()
        .Contain(date => Math.Abs((date - currentTime).TotalMilliseconds) <= timeTolerance.TotalMilliseconds)
        .Which.Should().BeCloseTo(currentTime, timeTolerance);
}

关键说明

之前的写法错误在于:Contain的谓词需要返回bool表示是否匹配,但直接调用.Should().BeCloseTo()会在不匹配时抛出断言异常,而非返回false,这不符合Contain的逻辑预期。通过手动计算时间差的布尔判断,才能让Contain正确识别匹配项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 20:35:55