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();
我在这个实例中使用 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();