如何指示AutoFixture不打扰填写某些属性?

Vac*_*ano 24 .net c# autofixture

我有一组嵌套得相当深的数据访问类.

要构建其中5个列表,需要AutoFixture超过2分钟.每单元测试2分钟就可以了.

如果我手工编写它们,我只会编写我需要的代码,因此它会更快地初始化.有没有办法告诉AutoFixture只做一些属性,所以它不能花时间在我不需要的结构区域?

例如:

public class OfficeBuilding
{
   public List<Office> Offices {get; set;}
}

public class Office
{
   public List<PhoneBook> YellowPages {get; set;}
   public List<PhoneBook> WhitePages {get; set;}
}

public class PhoneBook
{
    public List<Person> AllContacts {get; set;}
    public List<Person> LocalContacts {get; set;}
}

public class Person
{
   public int ID { get; set; }
   public string FirstName { get; set;}
   public string LastName { get; set;}
   public DateTime DateOfBirth { get; set; }
   public char Gender { get; set; }
   public List<Address> Addresses {get; set;}
}

public class Addresses
{
   public string Address1 { get; set; }
   public string Address2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法告诉AutoFixture创建值OfficeBuilding.Offices.YellowPages.LocalContacts,但不打扰OfficeBuilding.Offices.YellowPages.AllContacts

Mar*_*ann 29

Nikos Baxevanis提供的答案提供了各种基于会议的方式来回答这个问题.为了完整起见,您还可以进行更多临时构建:

var phoneBook = fixture.Build<PhoneBook>().Without(p => p.AllContacts).Create();
Run Code Online (Sandbox Code Playgroud)

如果您希望Fixture实例始终执行此操作,您可以自定义它:

fixture.Customize<PhoneBook>(c => c.Without(p => p.AllContacts));
Run Code Online (Sandbox Code Playgroud)

每次Fixture实例创建一个PhoneBook实例时,它都会跳过AllContacts属性,这意味着你可以去:

var sut = fixture.Create<OfficeBuilding>();
Run Code Online (Sandbox Code Playgroud)

并且AllContacts属性将保持不变.


Nik*_*nis 11

一种选择是创建省略特定名称属性的自定义:

internal class PropertyNameOmitter : ISpecimenBuilder
{
    private readonly IEnumerable<string> names;

    internal PropertyNameOmitter(params string[] names)
    {
        this.names = names;
    }

    public object Create(object request, ISpecimenContext context)
    {
        var propInfo = request as PropertyInfo;
        if (propInfo != null && names.Contains(propInfo.Name))
            return new OmitSpecimen();

        return new NoSpecimen(request);
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以使用如下:

var fixture = new Fixture();
fixture.Customizations.Add(
    new PropertyNameOmitter("AllContacts"));

var sut = fixture.Create<OfficeBuilding>();
// -> The 'AllContacts' property should be omitted now.
Run Code Online (Sandbox Code Playgroud)

也可以看看:

  • 如今,“return new NoSpecimen(request);”(已过时)可以替换为“return new NoSpecimen();” (2认同)