使用Ninject在执行UnitTesting时使用Moq模拟对象

Ale*_*Dee 7 nunit unit-testing moq ninject-2

我在使用Ninject的UnitTesting项目中使用Moq时遇到了麻烦.

首先谈谈我的解决方案.它包含几个项目(BussinesLogic,DAL,Infrastructure ...).我的目标是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,所以我可能也需要模拟它,因为业务逻辑正在基于该messageObject做一些事情.所以我想以某种方式设置属性到该消息对象,然后在其上调用一些businessLogic方法,所以我可以看到逻辑是否正常工作.

我希望我没有太多复杂化.

请耐心等待,我对嘲弄和依赖注入完全陌生,但我愿意学习.

Rus*_*est 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();
 }
Run Code Online (Sandbox Code Playgroud)

  • 我不确定我是否会说在测试中使用DI是"糟糕的".次优可能;)您想要对测试做的事情是尽可能多地删除外部"东西"并仅使用您正在测试的东西.如果在测试中使用DI,则现在增加了依赖注入的复杂性.此时,您实际上正在测试您的DI以及被测物.您可能能够在测试中使用DI,但我还不需要.当使用DI时,任何东西都应该紧密耦合 - 包括DI,所以你不需要它. (5认同)
  • 这正是我想要做的.好的,所以在测试中使用DI容器是不好的我接受它?为什么会这样?我认为通过使用它,它可能会简化我的测试,所以我不必写:`var p = new Program(new StubHealthMonitor(),storageManagerMock,new LogManager(),new StubConfigurationManager());`我基本上认为我会让DI容器处理所有不直接涉及此测试的事情,但是涉及测试的一件事,我可以通过Moq指定我自己. (3认同)