通过 AutoFixture 使用私人 setter 测试数据填充 public 属性
Fill public property with private setter test data by AutoFixture
我想测试 ConfirmDownloadInvoiceDate
方法。此外,我想通过 ConfirmationDownloadInvoiceDate
属性 的测试数据创建 Order
个对象:
fixture.Create<Order>();
我的Order
class:
public class Order
{
public DateTime? ConfirmationDownloadInvoiceDate { get; private set; }
public void ConfirmDownloadInvoiceDate(IDateTimeProvider timeProvider)
{
if (ConfirmationDownloadInvoiceDate == null)
{
ConfirmationDownloadInvoiceDate = timeProvider.Now();
}
}
}
是否可以用测试数据填充属性?我尝试通过从 ISpecimenBuilder
创建新的 class 但它似乎不起作用。
根据设计,AutoFixture 仅在 public 可写时填写字段和属性,因为如果您不使用 AutoFixture,而是编写测试,那么作为客户端开发人员您可以自己做数据逐阶段排列。在上面的Order
class中,ConfirmationDownloadInvoiceDate
属性没有publicsetter,所以AutoFixture会忽略它。
显然,最简单的解决方法是使 setter public,但这并不总是必要的。
在这种特殊情况下,您可以通过告诉 AutoFixture 在创建 Order
对象时调用 ConfirmDownloadInvoiceDate
方法来自定义 Order
class 的创建。
一种方法是首先创建 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
class.
中
我想测试 ConfirmDownloadInvoiceDate
方法。此外,我想通过 ConfirmationDownloadInvoiceDate
属性 的测试数据创建 Order
个对象:
fixture.Create<Order>();
我的Order
class:
public class Order
{
public DateTime? ConfirmationDownloadInvoiceDate { get; private set; }
public void ConfirmDownloadInvoiceDate(IDateTimeProvider timeProvider)
{
if (ConfirmationDownloadInvoiceDate == null)
{
ConfirmationDownloadInvoiceDate = timeProvider.Now();
}
}
}
是否可以用测试数据填充属性?我尝试通过从 ISpecimenBuilder
创建新的 class 但它似乎不起作用。
根据设计,AutoFixture 仅在 public 可写时填写字段和属性,因为如果您不使用 AutoFixture,而是编写测试,那么作为客户端开发人员您可以自己做数据逐阶段排列。在上面的Order
class中,ConfirmationDownloadInvoiceDate
属性没有publicsetter,所以AutoFixture会忽略它。
显然,最简单的解决方法是使 setter public,但这并不总是必要的。
在这种特殊情况下,您可以通过告诉 AutoFixture 在创建 Order
对象时调用 ConfirmDownloadInvoiceDate
方法来自定义 Order
class 的创建。
一种方法是首先创建 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
class.