自动修复子列表示例

Autofixure sublist example

我有两个 class 具有一对多关系

class Book
{
    public int Id {get;set;}
    public int AuthorId {get;set;}
    public string BookName {get;set;}
}

class Author
{
    public int Id {get;set;}
    public string AuthorName {get;set;}
    public List<Book> Books {get;set;}
}

我想使用 AutoFixture 来建立作者列表,但是我无法设置与 author.Id 相关的 book.AuthorId 有人可以建议吗?

谢谢

默认情况下,AutoFixture 不知道如何关联类型,尤其是在它们之间没有明确关系的情况下。

最简单的解决方案是先创建 Author 实例,然后使用构建器设置 AuthorId 属性.

var fixture = new Fixture();
var author = fixture.Create<Author>();

var book = fixture.Build<Book>()
.With(x => x.AuthorId, author.Id)
.Create();

然而,当您必须创建多个实例时,这非常冗长并且不是很有帮助。 指示 AutoFixture 自动 link 这两个实体的一种更通用的方法是有效地“冻结” Authors 的集合并使每个创建的 Book 从中获取 AuthorId一个现有的(冻结的)Author.

您可以从 this gist 中的以下示例中找到 RandomFromFixedSequence<T> 的实现。

[Fact]
public void BooksHaveValidAuthorIds()
{
    var fixture = new Fixture();
    fixture.Customize(new RandomFromFixedSequence<Author>());

    fixture.Customize<Book>(c => c
        .With<string, Author>(x => x.AuthorId, v => v.Id));

    var authorIds = fixture.CreateMany<Author>().Select(x => x.Id);
    var book = fixture.Create<Book>();

    authorIds.Should().Contain(book.AuthorId);
}

该解决方案的灵感主要来自 Enrico Campidoglio 的博客 post General-purpose customizations with AutoFixture。检查一下,看看我是如何完成自定义实施的。