AutoFixture 全局注册类型

AutoFixture Register type globally

我在这个实例中使用 AutoFixture 来具体化包含 Mongo ObjectId 的对象,就像这样

Fixture fixture = new Fixture();
fixture.Register(ObjectId.GenerateNewId);

但我每次测试都这样做。是否可以通过某种方式为所有测试注册此全局变量?

没有办法全局(或静态)。

我通常做的是创建一个 TestConventions class,其中包含我想应用于每个测试的所有自定义设置。

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 的建议创建了一个约定 class,但我最终创建了一个 TestBase class,我在单元测试 class

中继承了它
  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());

你也可以这样做

    public class FixtureWithFoo: Fixture
    {
        public FixtureWithFoo()
        {
            Customizations.Add(new FooCustomization()); 
            //Or register something else
        }
    }

然后在你的测试中使用它

var fixture = new FixtureWithFoo();