2011-04-29 88 views
7

我在使用Ninject的UnitTesting項目中使用Moq時遇到問題。使用Moq嘲笑對象,在進行UnitTesting時使用Ninject

首先介紹一下我的解決方案。它包含多個項目(BussinesLogic,DAL,基礎設施......)。我的目標是UnitTest我在BussinessLogic項目中使用的邏輯。 該解決方案基本上是爲Windows服務,但我已經放入了邏輯,以便它可以獨立運行。我使用Ninject和我指定天氣我想使用ProductionModule或TestingModule(Windows服務使用ProductionModule,控制檯應用程序使用TestingModule)

我使用工廠模式來獲取ninject內核,只要我需要它在我的內部應用。

我的TestingModule繼承自NinjectModule,其中我重載Load()方法,並在那裏做綁定。例如:

Bind<IStorageManager>().To<StubStorageManager>();

我有StubStorageManager,但它是空的。它只包含來自IStorageManager的方法聲明。

我想要做的事情是(以俗語形式): 創建一個unitTest,我將創建一個指定TestingModule作爲其參數的新內核。然後我想創建一個模擬對象(讓我們來看一個IStorageManager的模擬)storageManagerMock。 IStorageManager中的一些方法返回一個messageObject,所以我可能也需要嘲笑這一點,因此bussiness邏輯正在做一些基於該messageObject的事情。所以我想以某種方式設置該消息對象的屬性,然後調用它的一些businessLogic方法,所以我可以看到邏輯是否正常工作。

我希望我沒有太複雜。

請耐心等待,我完全不懂嘲笑和依賴注入,但願意學習。

+0

可能重複:http://stackoverflow.com/questions/1465849/using-ioc-for-unit-testing – 2011-04-29 13:23:50

回答

12

我懷疑你真的想在你的測試中使用Ninject。使用ninject的重點在於你可以將所有東西解耦。如果可能的話,你也想嘗試保持與依賴容器本身的解耦。如果必須通過,或者通過創建所需對象的工廠並讓工廠通過集裝箱,則將其傳入。

我懷疑你可能想要做這樣的事情:

public void ATest(){ 
    //create a mock StorageManager 
    var managerMock = new Mock<IStorageManager>(); 
    //create a mock MessageObject to be used by business logic 
    var messageObjectMock = new Mock<MessageObject>(); 

    //have the storage manager return the mock message when required 
    managerMock.Setup(x => x.GetMessageObject()).Returns(messageObjectMock.Object); 
    //set up message expectations 
    messageObjectMock.Setup(x => x.ThisValueExpected).Returns(10); 
    messageObjectMock.Setup(x => x.ThisFunctionShouldBeCalled()).Verifiable("Function not called."); 

    //thing to test 
    BusinessLogicObject blo = new BusinessLogicObject(managerMock.Object); 
    blo.DoTheThingImTesting(); 

    //make sure the business logic called the expected function, or do whatever check you need... 
    messageObjectMock.Verify(); 
} 
+3

這正是我想做。好的,所以在測試中使用DI容器是不好的,我接受了嗎?爲什麼?我認爲通過使用它,它可能會簡化我的測試,所以我不必寫:'var p = new Program(new StubHealthMonitor(),storageManagerMock,new LogManager(),new StubConfigurationManager())''我基本上認爲我會讓DI容器處理所有不直接涉及此測試的事情,但是涉及測試的一件事情,我可以通過Moq自行指定。 – 2011-04-30 03:38:51

+5

我不確定我會說在測試中使用DI是「不好的」。次優可能;)你想要做的事情就是儘可能地去除外部的'東西',只使用你正在測試的東西。如果您在測試中使用DI,則現在增加了依賴注入的複雜性。此時,您正在測試您的DI以及待測物。儘管我從來不需要,但你也許能夠在你的測試中使用DI。在使用DI時,任何東西都不應該與任何東西緊密相連 - 包括DI,因此您不需要它。 – 2011-04-30 13:07:45