首页 > 解决方案 > 从模拟的通用函数中自动返回夹具值?

问题描述

我的测试使用 Moq 和 AutoFixture,它们通常非常冗长,因为它们有许多模拟 Setup() 调用来配置模拟以返回由 AutoFixture 创建的值。为了使测试更易于阅读和维护,我尝试将 AutoMoqCustomization 与 ConfigureMembers 功能结合使用,以避免不必要的 Setup() 调用。

大多数情况下,这是按预期工作的,但是我有一些带有 AutoMoqCustomization 似乎无法处理的通用函数(主要是 AutoMapper)的接口。我没有从 AutoFixture 返回该类型的实例,而是收到了一个模拟实例。

我可以通过包含通用函数的 Setup() 调用来实现我想要的行为,但我的目标是尽可能多地删除这些 Setup 调用。

我已经设置了下面的示例来重现问题(实际上我正在使用 AutoFixture 通过另一个对象的构造函数注入一个 IMapper 实例,并且该对象调用了 IMapper 接口,但这并不是看到问题所必需的行为)。

我期望调用 tosut.Map<object>()像调用 to 一样工作,返回在夹具中冻结sut.Map()的实例。object相反,在变量中,retB我看到了一个ObjectProxy.

在示例中包含设置返回值的注释行将Map<object>()导致测试通过,但我更愿意省略此调用,就像我可以省略 Setup() 调用一样Map()

通用功能是否应该自动配置?我设置不正确吗?

using AutoFixture;
using AutoFixture.AutoMoq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace UnitTestProject1
{
    public interface IMapper
    {
        object Map();
        object Map<T>();
    }

    [TestClass]
    public class Tests
    {
        [TestMethod]
        public void Test()
        {
            var f = new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true });
            var model = f.Freeze<object>();
            var sut = f.Create<IMapper>();

            //Mock.Get(sut).Setup(x => x.Map<object>()).ReturnsUsingFixture(f);

            var retA = sut.Map();
            var retB = sut.Map<object>();

            Assert.AreEqual(model, retA);
            Assert.AreEqual(model, retB);        }
    }
}

标签: c#moqautofixtureautomoq

解决方案


事实上,由于编写方式的限制,autofixture 中的 AutoMoq 自定义当前不支持通用方法,但是有一个问题/PR 可以集成它: https ://github.com/AutoFixture/AutoFixture/issues/ 1139

据我所知,它还没有合并,因为它会引入更高的 Moq 依赖版本。它利用DefaultValueProviderMoq 相对最近引入的属性将所有“默认值”职责委托给 AutoFixture,而不是让 Moq 递归地引入模拟对象。听起来正是你想要的。

从这个问题来看,如果您要引入与拉取请求引入的自定义类似的自定义,下面是一个示例:

var fixture = new Fixture();
fixture.Customize<string>(x => x.FromSeed(y => "asf"));
var mock = new Mock<IInterfaceWithGenericMethod>
{
    DefaultValueProvider = new AutoFixtureValueProvider(fixture)
};

Assert.Equal("asf", mock.Object.GenericMethod<string>());

推荐阅读