如何用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
相关产品推荐
相关产品推荐

