How to generate default UTC DateTime when using AutoFixture and AutoData?

Viewed 450

I have a Model class as below:

public class Students
{ 
     public string FirstName {get;set;}
     public string LastName {get;set;}
     public DateTime DateJoined {get;set;}
}

I am then using AutoFixture and AutoData to generate random students:

[Theory, AutoData]
public async Task Save_ShouldCreateStudent(Student student]
{
     var createdStudent = student;
     var createdStudentJoined = student.DateJoined; // This is in local date time format
}

The date created is not in UTC. I want to configure Autofixture to generate all datetimes in utc format by default.

During my research, I found the below example, but it is not valid for me, as it is using Fact and creates an instance of fixture. I want the datetime to be generated in UTC when I use Autodata and the value is generated from the classed passed in the method parameter itself.

Note: Below code is from my research and does not help me. I am looking for a way to autogenerate UTC from my code above for Student.DateJoined.

public class UtcConverter : ISpecimenBuilder
{
    private readonly ISpecimenBuilder builder;

    public UtcConverter(ISpecimenBuilder builder)
    {
        this.builder = builder;
    }

    public object Create(object request, ISpecimenContext context)
    {
        var t = request as Type;
        if (t == null && t != typeof(DateTime))
            return new NoSpecimen(request);

        var specimen = this.builder.Create(request, context);
        if (!(specimen is DateTime))
            return new NoSpecimen(request);

        return ((DateTime)specimen).ToUniversalTime();
    }

    [Fact]
    public void ResolveUtcDate()
    {
         var fixture = new Fixture();
         fixture.Customizations.Add(
             new UtcConverter(
                new RandomDateTimeSequenceGenerator()));
         var dt = fixture.Create<DateTime>();
         Assert.Equal(DateTimeKind.Utc, dt.Kind);
    }
}
1 Answers

Sounds like you want to create your own AutoDataAttribute

public class AutoDomainDataAttribute : AutoDataAttribute
{
    public AutoDomainDataAttribute ()
        : base(() => new Fixture().Customize(new MyDomainDataCustomization()))
    {
    }
}

where MyDomainDataCustomization is a customization that encapsulates adding your specification builders

public class MyDomainDataCustomization : ICustomization
{
     public void Customize(IFixture fixture)
     {
         fixture.Customizations.Add(
             new UtcConverter(
                 new RandomDateTimeSequenceGenerator()));
      }
}

So now you can decorate the test with your AutoData attribute.

[Theory]
[AutoDomainData]
public void ResolveUtcDate(DateTime dt)
{
    Assert.Equal(DateTimeKind.Utc, dt.Kind);
}
Related