AutoFixture - 添加自定义,以便使用对象 ID 创建所有字典键

AutoFixture - adding a cusomization so all dictionary keys are created using the object id

我不确定这是否可行,但我认为这值得一问。

我们有许多对象具有其他子对象的层次结构。我们不使用一系列 IEnumerable 集合,而是使用字典,这样当在 MongoDb 中查询数据时,它是 easy/fast 来遍历层次结构。例如:

在主模型中我们有类似的东西:

public Dictionary<string, TopLevelGroup> TopGroups { get; set; }

然后在 TopLevelGroup 中我们有类似的东西:

public Dictionary<string, SecondLevelGroup> SecondLevelGroups { get; set; }

键必须是一个字符串,以便它可以作为 ReferencedDictionary 存储在 Mongo 中(我认为这是正确的)并且可以通过以下操作简单地访问数据:

TopLevelGroup[keyA].SecondLevelGroup[keyB].Property

所有的键都是对象的 ID 属性(它们也有一个通用的 IDocument 接口,这要求所有文档都有一个 ID……当然)。

所以我想在 AutoFixture 中做的是让所有自动生成的字典都使用对象的 ID 作为键(而不是随机生成的字符串)。

我怀疑这有点疯狂且不受支持,但我想问一下以防万一,因为我目前不太了解 AutoFixture。

不,一点也不疯狂, 支持它。

这种情况正是 Customize 方法的用武之地。

使用该方法,您可以自定义对象的创建方式。

你也许可以这样做:

fixture.Customize<TopLevelGroup>(
    c => c.With(
        propertyPicker: x => x.SecondLevelGroups, 
        valueFactory: (IEnumerable<SecondLevelGroup> input) => input.ToDictionary(y => y.Id)));

fixture.Customize<MainModel>(
    c => c.With(
        propertyPicker: x => x.TopGroups, 
        valueFactory: (IEnumerable<TopLevelGroup> input) => input.ToDictionary(y => y.Id)));

With 方法用于指定 属性 的值。第一个参数是 属性 选择器,例如x => x.SecondLevelGroups

第二个参数要么是一个值,要么是一个值工厂。 valuefactory 可以接受输入,autofixture 将填充该输入。例如 IEnumerable<SecondLevelGroup> 然后我们可以用我们想要的键将其转换为字典。