【问题标题】:How to use IFixture.Build<T>() with AutoMoqCustomization when T is an interface?当 T 是接口时,如何将 IFixture.Build<T>() 与 AutoMoqCustomization 一起使用?
【发布时间】:2019-11-26 10:27:18
【问题描述】:

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

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() 的原因是我想为某个属性有一个特定的返回值,而让其余的属性仍然自动生成。但不幸的是,根据文档,当使用 Build() 时,Fixture 上的所有自定义都被绕过了。

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

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

【问题讨论】:

    标签: c# unit-testing mocking moq autofixture


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      我认为在 Autofixture 中执行此操作的惯用方法(无需创建自己的 ISpecimenBuilder 实现)将依赖于自定义创建的 Mock 样本以提供 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"));
      

      诚然,它不像在在检索项目之后自定义项目那样简洁,但它确实允许您将样本的设置与其创建分开,如果您需要重复使用它,这将是有益的应通过自动夹具创建的其他标本的标本。

      【讨论】:

        猜你喜欢
        • 2013-03-02
        • 1970-01-01
        • 2018-02-19
        • 1970-01-01
        • 2014-03-10
        • 1970-01-01
        • 1970-01-01
        • 2017-08-11
        • 1970-01-01
        相关资源
        最近更新 更多