Using autofac with moq

本文关键字:moq with autofac Using | 更新日期: 2023-09-27 18:14:00

我需要用特定的接口注册Autofac容器,对于这种情况,我想解决mock。

我该怎么做?

我试过:

var AppContainer = ApplicationContainer.GetApplicationContainer();  
var cb = new ContainerBuilder();
cb.RegisterType<Mock<IStudyLoader>>().As<IStudyLoader>().SingleInstance();
cb.Update(AppContainer);

我不想改变我的代码来解决IStudyLoader以外的东西,但Mock<IStudyLoader>不能替代IStudyLoader;例如,Mock<IStudyLoader>.Object可以替代IStudyLoader,但我不能注册Mock<IStudyLoader>.Object,因为它不是类型。

请纠正我;我总觉得我错过了什么。

(我有另一个限制,我不能使用其他容器ApplicationContainer.GetApplicationContainer())

(我认为最好在测试时手动注入依赖项,但这次我不想改变生产代码)

Using autofac with moq

我找到了解决方案,是的,这是可能的!

  var AppContainer = ApplicationContainer.GetApplicationContainer();
  var studyLoaderMock = new Mock<IStudyLoader>().Object;
  cb.RegisterInstance(studyLoaderMock).As<IStudyLoader>();
  cb.Update(AppContainer);

老问题,但是AutoFac现在从4.0.1版本开始支持Moq4并提供额外的软件包,您可以安装Autofac.Extras.Moq

    Install-Package Autofac.Extras.Moq

Autofac.Extras。Moq auto安装AutoFac和Moq

你不需要创建一个容器并注册StudyLoader。它由autoface . extras . moq隐式定义。

Autofac.Extras。Moq对于嵌套依赖很有价值。你不需要注册所有的依赖关系图。只模拟SystemUnderTest SUT对象

你可以实现你的测试用例如下所示:

         [TestFixture]
        class StudyLoaderTest
        {
            [Test]
            public void Test()
            {
                using (var mock = AutoMock.GetLoose())
                {
                    // The AutoMock class will inject a mock IStudyLoader
                    // into the StudyLoader constructor
                    //no need to create/configure a container
                    var studyLoader = mock.Create<StudyLoader>();               
                    Assert.AreEqual("hi AutoFac Moq", studyLoader.Name);
                }
            }
        }
         class StudyLoader : IStudyLoader
        {
            public string Name { get; set; } = "hi AutoFac Moq";
        }
         interface IStudyLoader
        {
            string Name { get; set; }
        }

您正在寻找的方法称为RegisterInstance:

var mock = ...;
var cb = new ContainerBuilder();
cb.RegisterInstance(mock.Object);
var container = cb.Build();
也就是说,已经注册了要模拟的接口的现有容器(在您的示例中是AppContainer)将无法解析实例。它将继续解析生产实例。

我强烈建议你遵循的"变通方法"是,不要在测试中涉及AppContainer,而是为你的测试构建一个量身定制的容器,这样你就可以更好地控制里面的内容。其效果是,您可以注册所需的模拟实例以及SUT。

我对autofac没有特别的经验,但是我使用过的大多数其他容器都允许注册已经创建的对象实例。因此,您可以创建mock,然后注册mock。对象作为IStudyLoader的实现。关于如何做到这一点,请参考autoface文档。

既然问了这个问题,现在有一个AutoFac.Extras.Moq包,由AutoFac支持:

http://autofaccn.readthedocs.io/en/latest/integration/moq.html

这允许您在单元测试中动态创建依赖项。