首页 > 解决方案 > AutoFixture - 添加自定义,以便使用对象 ID 创建所有字典键

问题描述

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

我们有许多具有其他子对象层次结构的对象。我们不使用一系列 IEnumerable 集合,而是使用字典,以便在 MongoDb 中查询数据时,可以轻松/快速地遍历层次结构。例如:

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

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。

标签: c#mongodbunit-testing.net-coreautofixture

解决方案


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

该场景是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。valuefactory 可以接受一个输入,自动夹具将填充该输入。例如IEnumerable<SecondLevelGroup>,然后我们可以使用我们想要的键将其转换为字典。


推荐阅读