【发布时间】:2019-09-06 18:52:58
【问题描述】:
给定
这是我正在测试的类结构。
public class Company
{
public List<Department> Departments { get; set; }
}
public class Department
{
public List<Employee> Employees { get; set; }
}
public class Employee
{
public string Name { get; set; }
public DateTime HireDate { get; set; }
}
当 AutoFixture 被告知 Create<Company>() 时,我希望将 Employee 的自定义对象添加到 Department.Employees。
我认为应该这样写:
_fixture.Customize<Department>(
c => c.Do(d => d.Employees
.Add(_fixture.Build<Employee>()
.With(e => e.Name, "simple name")
.Create())));
_fixtrue.Create<Company>();
然而
当我运行测试时,Company.Departments 属性填充了 3 个对象,这三个对象中的每一个都有一个填充有 3 个对象(预期为 4 或 1)的 Department.Employees 列表,并且没有一个 Employee 对象有指定的名称。 为什么?
可能相关
我还在夹具上使用AutoNSubstituteCustomization 和ISpecimenBuilder 的本地实现来处理不相关的类型。
ISpecimenBuilder 是:
public class PropertyTypeOmission
{
public SelectionContext<TDeclaringType> For<TDeclaringType>()
{
return new SelectionContext<TDeclaringType>();
}
public class SelectionContext<TDeclaringType>
{
public OmitMemberTypeByType Omitting<TPropertyType>()
{
return new OmitMemberTypeByType(typeof(TDeclaringType), typeof(TPropertyType));
}
public OmitMemberTypeByType Omitting<TMemberType>(Expression<Func<TDeclaringType, TMemberType>> select)
{
var memberExp = GetMemberExpression(select);
var property = GetPropertyInfo(memberExp);
if (property != null)
{
return new OmitMemberTypeByType(typeof(TDeclaringType), property.PropertyType);
}
var field = GetFieldInfo(memberExp);
if (field != null)
{
return new OmitMemberTypeByType(typeof(TDeclaringType), field.FieldType);
}
throw new ArgumentException("Only field or property selectors allowed");
}
private static PropertyInfo GetPropertyInfo(MemberExpression memberExp)
{
if (!(memberExp.Member is PropertyInfo property))
{
return null;
}
return property;
}
private static MemberExpression GetMemberExpression<TMemberType>(Expression<Func<TDeclaringType, TMemberType>> select)
{
if (!(select.Body is MemberExpression memberExp))
{
throw new ArgumentException("only member expressions are allowed");
}
return memberExp;
}
private static FieldInfo GetFieldInfo(MemberExpression memberExp)
{
if (!(memberExp.Member is FieldInfo field))
{
return null;
}
return field;
}
}
}
public class OmitMemberTypeByType : ISpecimenBuilder
{
private Type _declaringType;
private Type _memberType;
public OmitMemberTypeByType(Type declaringType, Type memberType)
{
_declaringType = declaringType;
_memberType = memberType;
}
public object Create(object request, ISpecimenContext context)
{
if ((!(request is PropertyInfo propertyInfo)
|| propertyInfo.DeclaringType != _declaringType
|| propertyInfo.PropertyType != _memberType)
&&
(!(request is FieldInfo fieldInfo)
|| fieldInfo.DeclaringType != _declaringType
|| fieldInfo.FieldType != _memberType))
{
return new NoSpecimen();
}
return new OmitSpecimen();
}
}
用作
_fixture.Customizations.Add(new PropertyTypeOmission().For<State>().Omitting(s => s.SqMiles));
【问题讨论】:
标签: autofixture