当 T 是接口时,如何将 IFixture.Build<T>() 与 AutoMoqCustomization 一起使用?

How to use IFixture.Build<T>() with AutoMoqCustomization when T is an interface?

我有一个带有一些只读属性的接口:

interface IItem
{
    string Name { get; }
    // ... more properties
}

使用 Fixture.Create() 方法,我可以使用 AutoMoqCustomization 创建一个模拟接口实例,如下所示:

var fixture = new Fixture();
fixture.Customize(new AutoMoqCustomization());

var mockedItem = fixture.Create<IItem>();

但是要使用 Fixture.Build().CreateMany() 创建这些接口实例的列表,我不能仅通过执行以下操作来完成:

var mockedItems = fixture
    .Build<IItem>()
    .With(x => x.Name, "Abc")
    .CreateMany();

我需要 Build() 的原因是我想对某个 属性 有一个特定的 return 值,而让其余的属性仍然是自动的产生。但不幸的是,根据文档,当使用 Build() 时,Fixture 上的所有定制都被绕过了。

我正在使用以下版本:AutoFixture 4.8.0、AutoFixture.AutoMoq 4.8.0 和 Moq 4.9.0。

有没有一种简单的方法可以实现这一点而无需定义我自己的ISpecimenBuilder

可以从对象中提取mock并进行配置

var mockedItems = fixture.CreateMany<IItem>(3);

foreach (var item in mockedItems) {
    Mock<IItem> mock = Mock.Get(item);
    mock.Setup(_ => _.Name).Returns("Abc");
}

我认为在 Autofixture 中执行此操作的惯用方法(无需创建您自己的 ISpecimenBuilder 实现)将依赖于自定义为提供 IItem 标本:

var fixture = new Fixture().Customize(new AutoMoqCustomization());
fixture.Customize<Mock<IItem>>(c => c.OmitAutoProperties()
                                     .Do(m => m.SetupGet(i => i.Name).Returns("Abc")));

var items = fixture.CreateMany<IItem>(3);
Assert.That(items.Select(i => i.Name), Is.All.EqualTo("Abc"));

诚然,它不像 检索项目后自定义项目那样简洁,但它确实允许您将样本的设置与其创建分开,如果您需要将该样本重新用于其他应由自动夹具创建的样本。