Unit testing with mvc api & ninject

Sorry if this comes across as a dumb question, I'm just not sure how to start writing some unit tests.

I have a solution containing an api project and unit test. Api has a repository / interface used to access data using ninject.

My question is how is my best way for unit test my api controllers. I read a little about Moq, but not sure if I need to use it, since I want to test my database.

I read that I need to use the [TestInitialize] attribute

 [TestInitialize] public void MyTestInitialize() { var kernel = NinjectWebCommon.CreatePublicKernel(); kernel.Bind<BusinessController>().ToSelf(); } 

My problem is that my test project does not allow CreatePublicKernel. When checking the NinjectWebCommon class in api, there is no CreatePublicKernel function.

What am I missing here?

+6
source share
1 answer

Ninject (or another DI library) is used only to provide dependencies in your controller constructor. For instance. if you need a BusinessController that requires two repositories, then the controller must have a constructor that expects these dependencies:

 public BusinessController(IUserRepository userRepository, IOrderRepository orderRepository) { _userRepository = userRepository; _orderRepository = orderRepository; } 

If you want to write unit tests for your controller, you must provide a mock implementation of these repositories. Use Moq or another structure to create mocks:

 var userRepositoryMock = new Mock<IUserRepository>(); var orderRepositoryMock = new Mock<IOrderRepository>(); // setup mocks here var controller = new BusinessController(userRepositoryMock.Object, orderRepositoryMock.Object); 

If you write integration tests for your controller, you must provide a real implementation of these repositories that use some real database.

 var userRepository = new NHibernateUserRepository(); var orderRepository = new NHibernateOrderRepository(); // prepare some data in database here var controller = new BusinessController(userRepository, orderRepository); 

You can move the controller instance to some method that runs before each test (the SetUp or TestInitialize method) to remove code duplication from your tests.


UPDATE: You can also use Ninject to test integration. Just create a Ninject module that will be used both with real applications and with integration tests:

 public class FooModule : NinjectModule { public override void Load() { Bind<IUserRepository>().To<NHibernateUserRepository>(); Bind<IOrderRepository>().To<NHibernateOrderRepository>(); Bind<BusinessController>().ToSelf(); } } 

Then use this module to create the kernel in the NinjectWebCommon.CreateKernel method and the kernel in the tests:

 var kernel = new StandardKernel(new FooModule()); var controller = kernel.Get<ValuesController>(); 
+8
source

Source: https://habr.com/ru/post/956396/


All Articles