2011-11-09 66 views
8

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

我该怎么办?

我已经试过:

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()

(我认为这是更好地手动注入测试时的依赖性,但我不想改变生产代码,这段时间)

回答

16

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

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

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

5

你正在寻找的方法被称为RegisterInstance

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

也就是说,现有容器(你的情况AppContainer)已经有一个注册为要嘲笑将不是接口能够解决实例。它将继续解决生产实例。

我强烈建议您遵循的“解决方法”是在您的测试中不涉及AppContainer,而是为您的测试构建一个专门定制的容器,以便您更好地控制内容而不是内容。效果是你可以随着SUT一起注册你需要的任何模拟实例。

0

老问题,但AutoFac现在,因为4.0.1版本支持Moq4并提供额外的包,你可以安装Autofac.Extras.Moq

Install-Package Autofac.Extras.Moq 

Autofac.Extras.Moq自动安装这两个AutoFac和起订量

你needn” t创建一个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; } 
     }