我在这种情况下使用AutoFixture来实现包含Mongo ObjectId的对象,像这样
Fixture fixture = new Fixture();
fixture.Register(ObjectId.GenerateNewId);
但是我在每次测试时都这样做。是否可以通过某种方式为所有测试注册此Globall?
没有办法<(或静态地>>)。我通常要做的是创建一个TestConventions
类,其中包含我要应用于每个测试的所有自定义项。
internal class TestConventions : CompositeCustomization
{
public TestConventions() :
base(
new MongoObjectIdCustomization())
{
}
private class MongoObjectIdCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Register(ObjectId.GenerateNewId);
}
}
}
然后,我将这些约定应用于每个测试:
var fixture = new Fixture().Customize(new TestConventions());
如果使用的是AutoFixture.XUnit2(或AutoFixture.NUnit)插件,则可以通过定义导入测试约定的属性来减少样板:
public class MyProjectAutoDataAttribute : AutoDataAttribute { public MyProjectAutoDataAttribute() : base( new Fixture().Customize(new TestConventions())) { } }
然后将其应用于您的测试用例:
[Theory, MyProjectAutoData] public void SomeFact(SomeClass sut) { }
我按照@drcastro的建议创建了一个约定类,但最终创建了一个在我的单元测试类中继承的TestBase类
public class TestBase { public IFixture GenerateNewFixture() { return new Fixture().Customize(new AutoFixtureConventions()); } } internal class AutoFixtureConventions : CompositeCustomization { public AutoFixtureConventions() : base( new MongoObjectIdCustomization()) { } private class MongoObjectIdCustomization : ICustomization { public void Customize(IFixture fixture) { fixture.Register(ObjectId.GenerateNewId); } } }
我通过注册ISpecimenBuilder来解决此问题,因为我需要在与PropertyInfo有关的某些条件上进行匹配。
private class MongoObjectIdSpecimenBuilder : ISpecimenBuilder { public object Create(object request, ISpecimenContext context) { if (request is PropertyInfo info && info.PropertyType == typeof(ObjectId) && ...) return ObjectId.GenerateNewId().ToString(); return new NoSpecimen(); } } // register the builder AutoFixture.Customizations.Add(new MongoObjectIdSpecimenBuilder());