Search code examples
c#.net-6.0autofixturenunit-3.0dateonly

Does AutoFixture support `DateOnly` for .NET6?


I'm getting exception on constructing DateOnly variables/fields with AutoFixture. (constructing of TimeOnly works fine)

AutoFixture.ObjectCreationExceptionWithPath : AutoFixture was unable to create an instance from System.DateOnly because creation unexpectedly failed with exception. Please refer to the inner exception to investigate the root cause of the failure.

AutoFixture, AutoFixture.NUnit3 nugets version: 4.17.0

using AutoFixture;
using AutoFixture.NUnit3;
using NUnit.Framework;

namespace UnitTests
{
  [TestFixture]
  public class AutoFixtureCreateTests
  {
    private readonly Fixture fixture = new();

    [SetUp]
    public void Setup()
    {
      var date = fixture.Create<DateOnly>();  //fails
      var time = fixture.Create<TimeOnly>();  //works fine
    }

    [Test, AutoData]
    public void CreateString(string str) { } //works fine

    [Test, AutoData]
    public void CreateDateOnly(DateOnly date) { } //fails

    [Test, AutoData]
    public void CreateTimeOnly(TimeOnly time) { } //works fine
  }
}

Solution

  • The answer: at the moment does not. There is a pull request: https://github.com/AutoFixture/AutoFixture/pull/1305 (however it's in open state almost for a year, without any milestones)

    But there is a workaround. My temporary solution is to create AutoFixture customization (CustomFixture.cs) file and include it to the project:

    using AutoFixture;
    using AutoFixture.NUnit3;
    
    namespace UnitTests
    {
      public class CustomFixture
      {
        public static Fixture Create()
        {
          var fixture = new Fixture();
          fixture.Customize<DateOnly>(composer => composer.FromFactory<DateTime>(DateOnly.FromDateTime));
          return fixture;
        }
      }
    
      public class CustomAutoDataAttribute : AutoDataAttribute
      {
        public CustomAutoDataAttribute()
          : base(()=>CustomFixture.Create())
        {}
      }
    }
    

    After it include customization in the test code:

    using AutoFixture;
    using AutoFixture.NUnit3;
    using NUnit.Framework;
    
    namespace UnitTests
    {
      [TestFixture]
      public class AutoFixtureCreateTests
      {
        private readonly Fixture fixture = 
          CustomFixture.Create();  //custom factory
    
        [SetUp]
        public void Setup()
        {
          var date = fixture.Create<DateOnly>();  //now works
          var time = fixture.Create<TimeOnly>();  
        }
    
        [Test, AutoData]
        public void CreateString(string str) { } 
    
        [Test, CustomAutoData] //custom attribute
        public void CreateDateOnly(DateOnly date) { } //now works
    
        [Test, AutoData]
        public void CreateTimeOnly(TimeOnly time) { } 
      }
    }