12

我正在处理许多项目,每个项目都包含一个 DateProcessed 属性(一个可为空的 DateTime),并希望断言该属性设置为当前日期。当它通过处理程序时,日期都略有不同。

我想测试所有 DateProcessed 属性是否具有相对性(100 毫秒)最近的 DateTime。

Fluent Assertions 具有 .BeCloseTo 方法,该方法非常适用于单个项目。但我想将它用于整个系列。但是在查看集合时,它不能通过 Contains() 获得。

一个简化的例子...

[TestFixture]
public class when_I_process_the_items
{
    [SetUp]
    public void context()
    {
        items = new List<DateTime?>(new [] { (DateTime?)DateTime.Now, DateTime.Now, DateTime.Now } );
    }

    public List<DateTime?> items;

    [Test]
    public void then_first_item_must_be_set_to_the_current_time()
    {
        items.First().Should().BeCloseTo(DateTime.Now, precision: 100);
    }

    [Test]
    public void then_all_items_must_be_set_to_the_current_time()
    {
        items.Should().Contain .... //Not sure? :(
    }

}
4

3 回答 3

24

您可以在 3.5 中通过将选项配置为ShouldBeEquivalentTo. 例如:

result.ShouldBeEquivalentTo(expected, options =>
{
    options.Using<DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation)).WhenTypeIs<DateTime>();
    return options;
});

或简而言之:

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

如果要全局设置,请在测试框架的夹具设置方法中实现以下内容:

AssertionOptions.AssertEquivalencyUsing(options =>
{
    options.Using<DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation)).WhenTypeIs<DateTime>();
    options.Using<DateTimeOffset>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation)).WhenTypeIs<DateTimeOffset>();
    return options;
});
于 2015-08-05T09:17:23.150 回答
3

作为对您问题的直接回答,您可以执行类似items.Should().OnlyContain(i => (i - DateTime.Now) < TimeSpan.FromMilliseconds(100)).

但是,依赖于的单元测试DateTime.Now是一种非常糟糕的做法。你可以做的是引入这样的东西:

public static class SystemContext
{
    [ThreadStatic]
    private static Func<DateTime> now;

    public static Func<DateTime> Now
    {
        get { return now ?? (now = () => DateTime.Now); }
        set { now = value; }
    }
}

然后代替参考DateTime.Now,用于SystemContext.Now()获取当前时间。如果这样做,您可以像这样为特定单元测试“设置”当前时间:

SystemContext.Now = () => 31.March(2013).At(7, 0);
于 2014-07-16T11:13:07.717 回答
-1

我就是这样解决的...

[Test]
public void then_all_items_must_be_set_to_the_current_time()
{
    items.Should().OnlyContain(x => DateTime.Now.Subtract(x.Value).Milliseconds <= 100);
}

但是,如果有人知道“开箱即用”的 Fluent Assertions 方法,请告诉我。

于 2014-07-16T11:00:22.727 回答