2011-04-29 44 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