Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking an object with Moq, using Ninject when doing UnitTesting

I'm having trouble using Moq in a UnitTesting project with Ninject.

First a few lines about my solution. It contains several projects (BussinesLogic, DAL, Infrastructure...). My goal is to UnitTest the logic i'm using in BussinessLogic project. The solution is basicly for a windows service, but i've put in the logic so it can be run standalone. I'm using Ninject and i specify weather i want to use the ProductionModule or the TestingModule (windows service uses ProductionModule, console app uses TestingModule)

I'm using a factory pattern to get ninject kernel whenever i need it inside my application.

My TestingModule inherits from NinjectModule where i override the Load() method and there i do the binding. For instance:

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

I have the StubStorageManager but it's empty. It contains just the declaration of methods from IStorageManager.

The thing i would like to do is (in laymans terms): Create a unitTest where i would create a new kernel specifying the TestingModule as it's parameter. Then i would like to create a mock object (let's say a mock of IStorageManager) storageManagerMock. Some method in IStorageManager returns a messageObject so i would probably need to mock that too, couse the bussiness logic is doing something based on that messageObject. So i would like to somehow set properties to that message object and then call some businessLogic method on it, so i can see if the logic works correctly.

I hope i didn't complicate it too much.

Please bear with me, i'm completely new to mocking and dependency injection, but am willing to learn.

like image 352
Alex Dee Avatar asked Apr 29 '11 13:04

Alex Dee


People also ask

What can be mocked with Moq?

You can use Moq to create mock objects that simulate or mimic a real object. Moq can be used to mock both classes and interfaces.

How does Moq mock work?

Mock objects allow you to mimic the behavior of classes and interfaces, letting the code in the test interact with them as if they were real. This isolates the code you're testing, ensuring that it works on its own and that no other code will make the tests fail.

Is mocking a dependency injection?

Dependency injection is a way to scale the mocking approach. If a lot of use cases are relying on the interaction you'd like to mock, then it makes sense to invest in dependency injection. Systems that lend themselves easily to dependency injection: An authentication/authorization service.

Is Moq a testing framework?

The Moq framework is an open source unit testing framework that works very well with . NET code and Phil shows us how to use it.


1 Answers

I doubt you really want to be using Ninject in your tests. The whole point of using ninject is that you can decouple everything. You also want to try and keep everything decoupled from the dependency container itself if possible. Pass it in if you have to, or pass in factories that create the required object and have the container pass in the factory.

I suspect you probably want to do something like this:

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();
 }
like image 130
Russell Troywest Avatar answered Nov 10 '22 16:11

Russell Troywest