全局AutoFixture寄存器类型

本文关键字:类型 寄存器 AutoFixture 全局 | 更新日期: 2023-09-27 18:11:52

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

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

但是我每次考试都这样做。是否有可能以某种方式为所有测试注册这个全局?

全局AutoFixture寄存器类型

没有办法全局(或静态)做到这一点。

我通常做的是创建一个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);
            }
        }
    }

你也可以这样做

    public class FixtureWithFoo: Fixture
    {
        public FixtureWithFoo()
        {
            Customizations.Add(new FooCustomization()); 
            //Or register something else
        }
    }
然后在你的测试 中使用它
var fixture = new FixtureWithFoo();

我通过注册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());