如何使用AutoFixture生成Person类所有姓名组合的测试数据
AutoFixture生成姓名全排列Person实例的实现方法
AutoFixture默认以随机方式生成测试数据,要实现指定姓名集合的全排列组合生成,有两种常用实现方式:
方案1:临时场景,结合LINQ笛卡尔积实现
该写法无需自定义扩展,适合仅单次生成的场景:
// 实体类定义 public class Person { public string Firstname { get; set; } public string Lastname { get; set; } } // 初始化Fixture var fixture = new Fixture(); // 预设的名、姓集合 var firstnames = new[] { "John", "Jane" }; var lastnames = new[] { "Doe", "Smith" }; // 生成全排列Person列表 var persons = firstnames .SelectMany(first => lastnames.Select(last => fixture.Build<Person>() .With(p => p.Firstname, first) .With(p => p.Lastname, last) // 若不需要AutoFixture自动生成其他属性的随机值,可开启下方配置 // .OmitAutoProperties() .Create() )) .ToList();
上述示例会生成4个Person实例,对应John Doe、John Smith、Jane Doe、Jane Smith所有组合。
方案2:复用场景,自定义生成器
如果需要在多处使用该全排列生成逻辑,可以自定义ISpecimenBuilder注册到Fixture中,后续直接调用即可:
// 自定义Person全排列生成器 public class PersonCombinatorialBuilder : ISpecimenBuilder { private readonly string[] _firstnames; private readonly string[] _lastnames; private int _currentIndex; public PersonCombinatorialBuilder(string[] firstnames, string[] lastnames) { _firstnames = firstnames; _lastnames = lastnames; _currentIndex = 0; } public object Create(object request, ISpecimenContext context) { if (request is Type type && type == typeof(Person)) { if (_currentIndex >= _firstnames.Length * _lastnames.Length) { return new NoSpecimen(); } var firstIndex = _currentIndex / _lastnames.Length; var lastIndex = _currentIndex % _lastnames.Length; _currentIndex++; return new Person { Firstname = _firstnames[firstIndex], Lastname = _lastnames[lastIndex] }; } return new NoSpecimen(); } } // 使用方式 var fixture = new Fixture(); var firstnames = new[] { "John", "Jane" }; var lastnames = new[] { "Doe", "Smith" }; // 注册自定义生成器 fixture.Customizations.Add(new PersonCombinatorialBuilder(firstnames, lastnames)); // 生成全排列列表,传入参数为总组合数:名数量 * 姓数量 var persons = fixture.CreateMany<Person>(firstnames.Length * lastnames.Length).ToList();
如果Person类包含其他需要AutoFixture自动生成的属性,可将生成器中直接new Person的逻辑替换为context.Resolve<Person>()生成基础实例,再覆盖Firstname和Lastname属性即可。
内容的提问来源于stack exchange,提问作者arkord
相关产品推荐
相关产品推荐

