33

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

构建一个包含 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; }
}

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

4

2 回答 2

44

Nikos Baxevanis 提供的答案提供了各种基于约定的方法来回答问题。为了完整起见,您还可以进行更临时的构建:

var phoneBook = fixture.Build<PhoneBook>().Without(p => p.AllContacts).Create();

如果您希望您的 Fixture 实例始终这样做,您可以自定义它:

fixture.Customize<PhoneBook>(c => c.Without(p => p.AllContacts));

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

var sut = fixture.Create<OfficeBuilding>();

并且 AllContacts 属性将保持不变。

于 2013-08-23T12:24:05.857 回答
18

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

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);
    }
}

您可以按如下方式使用它:

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

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

也可以看看:

于 2013-08-21T08:49:08.220 回答