Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何指示AutoFixture不必填写某些属性?_C#_.net_Autofixture - Fatal编程技术网

C# 如何指示AutoFixture不必填写某些属性?

C# 如何指示AutoFixture不必填写某些属性?,c#,.net,autofixture,C#,.net,Autofixture,我有一组嵌套得相当深的数据访问类 要构建其中5个的列表,AutoFixture需要2分钟以上的时间。每个单元测试2分钟的时间太长了 如果我是手工编写的,我只会编写我需要的代码,这样初始化会更快。有没有办法告诉AutoFixture只执行某些属性,这样它就不能花时间处理我不需要的结构区域 例如: public class OfficeBuilding { public List<Office> Offices {get; set;} } public class Office

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

要构建其中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; }
}
公共类办公楼
{
公共列表办公室{get;set;}
}
公课办公室
{
公共列表黄页{get;set;}
公共列表白页{get;set;}
}
公共类电话簿
{
公共列表所有联系人{get;set;}
公共列表本地联系人{get;set;}
}
公共阶层人士
{
公共int ID{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共日期时间出生日期{get;set;}
公共字符{get;set;}
公共列表地址{get;set;}
}
公共类地址
{
公共字符串地址1{get;set;}
公共字符串地址2{get;set;}
}

有没有一种方法可以告诉AutoFixture为
办公楼.Offices.YellowPages.LocalContacts
创建值,而不必为
办公楼.Offices.YellowPages.AllContacts

创建忽略特定名称属性的自定义项:

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);
    }
}
内部类propertynameomiter:ISpecimenBuilder
{
私有只读IEnumerable名称;
内部PropertyNameOmitter(参数字符串[]名称)
{
this.names=名称;
}
公共对象创建(对象请求,ISPecementContext上下文)
{
var propInfo=请求作为PropertyInfo;
if(propInfo!=null&&Name.Contains(propInfo.Name))
返回新样本();
返回新的NoSpecimen(请求);
}
}
您可以按以下方式使用它:

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

var sut = fixture.Create<OfficeBuilding>();
// -> The 'AllContacts' property should be omitted now.
var fixture=newfixture();
fixture.Customizations.Add(
新PropertyNameOmitter(“所有联系人”);
var sut=fixture.Create();
//->“AllContacts”属性现在应该省略。

另见:


Nikos Baxevanis提供的答案提供了各种基于惯例的方法来回答这个问题。为了完整性起见,您还可以进行更特别的构建:

var phoneBook = fixture.Build<PhoneBook>().Without(p => p.AllContacts).Create();
var phoneBook=fixture.Build().Without(p=>p.AllContacts.Create();
如果希望装置实例始终执行此操作,可以对其进行自定义:

fixture.Customize<PhoneBook>(c => c.Without(p => p.AllContacts));
fixture.Customize(c=>c.Without(p=>p.AllContacts));
每次Fixture实例创建PhoneBook实例时,它都会跳过AllContacts属性,这意味着您可以:

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

并且AllContacts属性将保持不变。

现在
返回新的NoSpecimen(请求)(过时)可以替换为
返回新的NoSpecimen()