使用AutoFixture生成一对多数据时如何绑定Book的AuthorId属性
AutoFixture 默认不会自动处理实体间的外键关联,你可以通过自定义生成规则实现绑定,以下是两种常用方案:
方案1:临时自定义构造规则(适合单次使用场景)
无需额外定义扩展类,直接在构造fixture时指定关联逻辑即可:
using AutoFixture; var fixture = new Fixture(); // 关闭默认循环引用检测,避免Author和Book的关联触发递归异常 fixture.Behaviors.OfType<ThrowingRecursionBehavior>() .ToList() .ForEach(b => fixture.Behaviors.Remove(b)); fixture.Behaviors.Add(new OmitOnRecursionBehavior()); // 自定义Author生成规则,绑定Book的AuthorId fixture.Customize<Author>(c => c .Do(author => { // 生成3个关联的Book,可自行调整数量 var relatedBooks = fixture.CreateMany<Book>(3).ToList(); relatedBooks.ForEach(book => book.AuthorId = author.Id); author.Books = relatedBooks; }) ); // 直接生成Author列表,所有关联Book的AuthorId已自动匹配对应Author的Id var authorList = fixture.CreateMany<Author>(10).ToList();
方案2:全局自定义生成器(适合多处复用场景)
如果项目中多处需要生成带关联Book的Author,可以实现自定义ISpecimenBuilder统一处理:
using AutoFixture; using AutoFixture.Kernel; public class AuthorWithBooksBuilder : ISpecimenBuilder { private readonly int _bookCountPerAuthor; public AuthorWithBooksBuilder(int bookCountPerAuthor = 3) { _bookCountPerAuthor = bookCountPerAuthor; } public object Create(object request, ISpecimenContext context) { if (request is not Type type || type != typeof(Author)) { return new NoSpecimen(); } // 生成基础Author属性 var author = new Author { Id = (int)context.Resolve(typeof(int)), AuthorName = (string)context.Resolve(typeof(string)) }; // 生成关联Book并绑定外键 var books = ((IEnumerable<Book>)context.Resolve(typeof(IEnumerable<Book>))) .Take(_bookCountPerAuthor) .ToList(); books.ForEach(book => book.AuthorId = author.Id); author.Books = books; return author; } }
使用方式:
var fixture = new Fixture(); // 关闭递归检测逻辑和方案1一致 fixture.Behaviors.OfType<ThrowingRecursionBehavior>() .ToList() .ForEach(b => fixture.Behaviors.Remove(b)); fixture.Behaviors.Add(new OmitOnRecursionBehavior()); // 注册全局生成器,可指定每个Author关联的Book数量 fixture.Customizations.Add(new AuthorWithBooksBuilder(bookCountPerAuthor: 2)); // 生成Author列表 var authorList = fixture.CreateMany<Author>(10).ToList();
内容的提问来源于stack exchange,提问作者Emily
相关产品推荐
相关产品推荐

