I want to test ConfirmDownloadInvoiceDate
method. In addition, I want to create Order
objects with my test data for ConfirmationDownloadInvoiceDate
property by:
fixture.Create<Order>();
My Order
class:
public class Order
{
public DateTime? ConfirmationDownloadInvoiceDate { get; private set; }
public void ConfirmDownloadInvoiceDate(IDateTimeProvider timeProvider)
{
if (ConfirmationDownloadInvoiceDate == null)
{
ConfirmationDownloadInvoiceDate = timeProvider.Now();
}
}
}
Is it possible to fill that property with test data? I tried by create new class from ISpecimenBuilder
but it seems it does not work.
By design, AutoFixture only fills out fields and properties when they're publicly writable, because that's what you can do as a client developer yourself, if you, instead of using AutoFixture, write the test data arrange phase by hand. In the above Order
class, the ConfirmationDownloadInvoiceDate
property doesn't have a public setter, so AutoFixture will ignore it.
The easiest workaround, obviously, is to make the setter public, but this is not always warranted.
In this particular case, you can customize creation of the Order
class by telling AutoFixture that it should invoke the ConfirmDownloadInvoiceDate
method when it creates Order
objects.
One way to do that would be to first create a test-specific Stub implementation of IDateTimeProvider
, for example like this:
public class StubDateTimeProvider : IDateTimeProvider
{
public StubDateTimeProvider(DateTime value)
{
this.Value = value;
}
public DateTime Value { get; }
public DateTime Now()
{
return this.Value;
}
}
You could also use a dynamic mock library, like Moq, NSubstitute, or the like.
Use the stub to call the ConfirmDownloadInvoiceDate
method, for example like this:
[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);
}
This test passes. You should consider packaging the above customization in an ICustomization
class.