【问题标题】:Using autofac with moq将 autofac 与最小起订量一起使用
【发布时间】:2011-12-25 02:20:49
【问题描述】:

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

我该怎么做?

我试过了:

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

我不想更改我的代码来解决 IStudyLoader 以外的问题,但 Mock&lt;IStudyLoader&gt; 不能替代 IStudyLoader;例如Mock&lt;IStudyLoader&gt;.Object 可以替代IStudyLoader,但我无法注册Mock&lt;IStudyLoader&gt;.Object,因为它不是一个类型。

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

(我还有个限制,不能使用ApplicationContainer.GetApplicationContainer()以外的容器)

(我觉得测试的时候还是手动注入依赖比较好,但是这次不想改生产代码。)

【问题讨论】:

    标签: c# moq autofac


    【解决方案1】:

    我找到了解决办法,是的,有可能!

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

    【讨论】:

      【解决方案2】:

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

          Install-Package Autofac.Extras.Moq
      

      Autofac.Extras.Moq 自动安装 AutoFac 和 Moq

      您无需创建 Container 并注册 StudyLoader。它由 Autofac.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; }
              }
      

      【讨论】:

        【解决方案3】:

        你要找的方法叫RegisterInstance

        var mock = ...;
        var cb = new ContainerBuilder();
        cb.RegisterInstance(mock.Object);
        var container = cb.Build();
        

        也就是说,已经注册了您要模拟的接口的现有容器(在您的情况下为 AppContainer)将无法解析实例。它将继续解析生产实例。

        我强烈建议您遵循的“解决方法”是不要将 AppContainer 包含在您的测试中,而是构建一个为您的测试量身定制的容器,以便您更好地控制其中的内容。效果是您可以将所需的任何模拟实例与SUT 一起注册。

        【讨论】:

          【解决方案4】:

          我对 autofac 没有特别的经验,但是我使用过的大多数其他容器都允许注册一个已经创建的对象实例。所以你可以创建你的模拟,然后注册 mock.Object 作为 IStudyLoader 的实现。有关如何执行此操作的信息,请参阅 autofac 文档。

          【讨论】:

            【解决方案5】:

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

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

            这允许您在单元测试中创建 on the fly 依赖项。

            【讨论】:

              猜你喜欢
              • 2017-03-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-12-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多