使用moq的autofac

Del*_*ate 12 c# moq autofac

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

我该怎么做?

我试过了:

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

我不想改变我的代码来解决别的问题IStudyLoader,但Mock<IStudyLoader>不能替代IStudyLoader; 例如Mock<IStudyLoader>.Object可以替代IStudyLoader,但我不能注册,Mock<IStudyLoader>.Object因为它不是一种类型.

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

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

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

Del*_*ate 17

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

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


Pet*_*old 7

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

var mock = ...;
var cb = new ContainerBuilder();
cb.RegisterInstance(mock.Object);
var container = cb.Build();
Run Code Online (Sandbox Code Playgroud)

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

我强烈建议您遵循的"解决方法"是不要让AppContainer参与您的测试,而是为您的测试构建一个容器,以便您可以更好地控制其中的内容.结果是你可以在SUT中注册你需要的任何模拟实例.


M.H*_*san 5

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

    Install-Package Autofac.Extras.Moq
Run Code Online (Sandbox Code Playgroud)

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

您无需创建容器并注册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; }
        }
Run Code Online (Sandbox Code Playgroud)