Autofixture 生成不重复的集合(按 ID)

2023-12-29

我有以下课程:

public class Foo
{
    public List<DescriptionInfo> Descriptions { get; set; }
}


public class DescriptionInfo
{
    public int LanguageId { get; set; }
    public string Value { get; set; }
}

我想使用 Autofixture 创建 Foo 实例。但是,LanguageId 必须来自预定义列表。因此我创建了以下定制:

public class LanguageIdSpecimenBuilder : ISpecimenBuilder
{
    private static readonly List<int> LanguageIds = new List<int> {
        1,
        2,
        666,
    };

    public object Create(object request, ISpecimenContext context)
    {
        var info = request as PropertyInfo;
        if (info != null)
        {
            if (info.Name == "LanguageID")
            {
                return LanguageIds.GetRandomElement();
            }
        }
        return new NoSpecimen(request);
    }
}

现在一切都很好:

Fixture fixture = new Fixture();
fixture.Customizations.Add(new LanguageIdSpecimenBuilder());
var foo = fixture.Create<Foo>(); 

但是,还有一个要求:一种语言 ID 不能有重复的条目。我怎样才能实现这个目标?

EDIT:例如,有效实例是:

Foo1:
 - LanguageId: 1, Value: "english description_ae154c"
 - LanguageId: 2, Value: "zuzulu_510b7g"

Foo2:
 - LanguageId: 1, Value: "english description_87f5de"
 - LanguageId: 666, Value: "chinese_35e450"
 - LanguageId: 2, Value: "zuzulu_fe830d"

无效实例:

Foo1:
 - LanguageId: 1, Value: "_04dcd6"
 - LanguageId: 1, Value: "_66ccc4"
 - LanguageId: 2, Value: "zuzulu_c05b0f"

首先,我建议您的 POC 可以更精确。如果您不允许使用相同的描述LanguageID在列表中,您可以重塑您的 POC,如下所示:

public class Foo
{
    public ISet<DescriptionInfo> Descriptions { get; set; }
}

public class DescriptionInfo
{
    public int LanguageID { get; set; }
    public string Value { get; set; }

    public override bool Equals(object obj)
    {
        var anotherInfo = (DescriptionInfo)obj;
        return anotherInfo.LanguageID == LanguageID;
    }

    public override int GetHashCode()
    {
        return LanguageID;
    }
}

问题就消失了:

fixture.Customizations.Add(new TypeRelay(typeof(ISet<DescriptionInfo>),
  typeof(HashSet<DescriptionInfo>)));
fixture.Customizations.Add(new LanguageIdSpecimenBuilder());
var foo = fixture.Create<Foo>();

如果您不能/不想重塑您的 POC,您应该在自定义构建器中关注您想要正确设置的属性 -Descriptions.

public object Create(object request, ISpecimenContext context)
{
    var info = request as PropertyInfo;
    if (info != null && info.Name == "Descriptions" && info.DeclaringType == typeof(Foo))
    {
        if (info.Name == "Descriptions")
        {
            return context.Create<List<DescriptionInfo>>()
             .GroupBy(g => g.LanguageId)
             .Select(g => g.First())
             .ToList();
         }
    }
    if (info != null && info.Name == "LanguageId" && info.DeclaringType == typeof(DescriptionInfo))
    {
        return LanguageIds.GetRandomElement();
    }
    return new NoSpecimen(request);
}

最后注意 - 你的代码片段是错误的 - 字符串比较区分大小写;所以应该是info.Name == "LanguageId",检查声明属性的类型也是个好主意 - 而不仅仅是属性名称。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Autofixture 生成不重复的集合(按 ID) 的相关文章

随机推荐