我在使用 AutoFixture 构造 DateOnly 变量/字段时遇到异常。 (TimeOnly 的构建工作正常)
AutoFixture.ObjectCreationExceptionWithPath :AutoFixture 无法从 System.DateOnly 创建实例,因为创建意外失败并出现异常。请参考内部异常来排查失败的根本原因。
AutoFixture、AutoFixture.NUnit3 nugets 版本: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
}
}
答案:目前还没有。 有一个拉取请求:https://github.com/AutoFixture/AutoFixture/pull/1305 (然而它处于开放状态快一年了,没有任何里程碑)
但是有一个解决方法。 我的临时解决方案是创建 AutoFixture 自定义 (CustomFixture.cs) 文件并将其包含到项目中:
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())
{}
}
}
在测试代码中包含自定义之后:
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) { }
}
}
不,但将来可能会发生(参见@Evgeny 的回答)。在代码中实现它的一种方法是为 dateonly 和 timeonly 创建可重用的固定装置自定义:
public class DateOnlyFixtureCustomization: ICustomization
{
void ICustomization.Customize(IFixture fixture)
{
fixture.Customize<DateOnly>(composer => composer.FromFactory<DateTime>(DateOnly.FromDateTime));
}
}
public class TimeOnlyFixtureCustomization: ICustomization
{
void ICustomization.Customize(IFixture fixture)
{
fixture.Customize<TimeOnly>(composer => composer.FromFactory<DateTime>(TimeOnly.FromDateTime));
}
}
然后可以在创建新夹具时使用它们,如下所示:
var fixture = new Fixture().Customize(new CompositeCustomization(
new DateOnlyFixtureCustomization(),
new TimeOnlyFixtureCustomization()
// Add other fixture customizations as needed
));