2011-11-09 95 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; } 
     }