通过 AutoFixture 用私有二传手测试数据填充公共属性



我想测试ConfirmDownloadInvoiceDate方法。此外,我想通过以下方式使用ConfirmationDownloadInvoiceDate属性的测试数据创建Order对象:

fixture.Create<Order>();

我的Order课:

public class Order
{       
public DateTime? ConfirmationDownloadInvoiceDate { get; private set; }
public void ConfirmDownloadInvoiceDate(IDateTimeProvider timeProvider)
{
if (ConfirmationDownloadInvoiceDate == null)
{
ConfirmationDownloadInvoiceDate = timeProvider.Now();
}
}
}

是否可以用测试数据填充该属性?我尝试从ISpecimenBuilder创建新类,但似乎不起作用。

根据设计,AutoFixture 仅在字段和属性可公开写入时才填写它们,因为如果您不使用 AutoFixture,而是手动编写测试数据排列阶段,这就是您作为客户端开发人员可以自己执行的操作。在上面的Order类中,ConfirmationDownloadInvoiceDate属性没有公共资源库,因此 AutoFixture 将忽略它。

显然,最简单的解决方法是公开二传手,但这并不总是有保证的。

在此特定情况下,可以通过告诉 AutoFixture 在创建对象时应调用ConfirmDownloadInvoiceDate方法Order自定义Order类的创建。

一种方法是首先创建一个特定于测试的IDateTimeProvider存根实现,例如:

public class StubDateTimeProvider : IDateTimeProvider
{
public StubDateTimeProvider(DateTime value)
{
this.Value = value;
}
public DateTime Value { get; }
public DateTime Now()
{
return this.Value;
}
}

您还可以使用动态模拟库,例如Moq,NSubstitute等。

使用存根调用ConfirmDownloadInvoiceDate方法,例如:

[Fact]
public void AutoFillConfirmationDownloadInvoiceDate()
{
var fixture = new Fixture();
fixture.Customize<Order>(c => c
.Do(o => o.ConfirmDownloadInvoiceDate(fixture.Create<StubDateTimeProvider>())));
var actual = fixture.Create<Order>();
Assert.NotNull(actual.ConfirmationDownloadInvoiceDate);
Assert.NotEqual(default(DateTime), actual.ConfirmationDownloadInvoiceDate);
}

此测试通过。应考虑将上述自定义项打包到ICustomization类中。

最新更新