Home > DeveloperSection > Articles > MVC 3 + Ninject + Moq + Unit Test Step By Step

MVC 3 Ninject Moq Unit Test Step By Step


ASP.NET MVC ASP.NET MVC 
Ratings:
1 Comment(s)
 6640  View(s)
Rate this:

MVC 3 + Ninject + Moq + Unit Test Step By Step

 

In the following example, I'll show you how to use Ninject on a simple ASP.Net MVC applicatoin, and I'll write a Unit Test for the Home Controller with Moq.

The MVC Applicatoin
Lets start with a plain MVC 3 applicaiton
Start Visual Studio 2010 and then create a new project, select ASP.NET MVC 3 Web Application.
In the Name and Solution Name text box, enter "SimpleNinjectDemo" then press OK.


Next, select "Internet Application", View Engine should be Razor, remember to check "Create a unit test project".  Click OK to continue.

MVC 3 + Ninject + Moq + Unit Test Step By Step


At this point, the newly created project should have file structure look like below picture

MVC 3 + Ninject + Moq + Unit Test Step By Step



Now add a "Services" folder to SimpleNinjectDemo project, like below

MVC 3 + Ninject + Moq + Unit Test Step By Step


Inside the Services folder, let us add an interface for messaging called IMessagingService.  We will be using the messaging service in our home controller that will be creating in the next couple of steps.


Add an interface called IMessagingService.cs under Services folder

namespace SimpleNinjectDemo.Services

{

    public interface IMessagingService

    {

        string HelloWorld();

    }

}


Now let's create the actual messaging service that is about to hook up to the previous IMessagingService interface. Add a class called MessagingService.cs under Services folder

namespace SimpleNinjectDemo.Services

{

    public class MessagingService : IMessagingService

    {

       public string HelloWorld()

       {

           return "Hello World";

       }

    }

}


At this point, the project folder should look like this

MVC 3 + Ninject + Moq + Unit Test Step By Step



With the Messaging Service in place, we can now start working on the controller to consume the service
Let's modify the HomeController as below

using System.Web.Mvc;

using SimpleNinjectDemo.Services;

 

namespace NinjectSimpleDemo.Controllers

{

    public class HomeController : Controller

    {

        private IMessagingService MessagingService { get; set; }

 

        public HomeController(IMessagingService messagingService)

        {

            this.MessagingService = messagingService;

        }

 

        public ActionResult Index()

        {

            ViewBag.Message = MessagingService.HelloWorld();

 

            return View();

        }

 

        public ActionResult About()

        {

            return View();

        }

    }

}


Ninject comes to rescue

As you can see, we added a constructor which has a parameter implementing IMessagingService. This technique is called Dependency Injection.

Ok, enough talk, let's compile and run the application to see what's the effect.

MVC 3 + Ninject + Moq + Unit Test Step By Step


Oops, the newly introduced HomeController constructor needs a MessagingService object as parameter, what should I do to create and pass it into HomeController?

... It's easy, here comes Ninject, it can help to solve the above problem in few lines of code.

 

Let's install Ninject.MVC3 using NuGet package installer.

MVC 3 + Ninject + Moq + Unit Test Step By Step



After Ninject.MVC3 installed, you'll notice the project will have a new folder App_Start and a file NinjectMVC3.cs or NinjectWebCommon.cs both are same under it

MVC 3 + Ninject + Moq + Unit Test Step By Step

OR

MVC 3 + Ninject + Moq + Unit Test Step By Step



This file acts as the setup file for Ninject, it takes care of all bindings and start up. Now let's modify NinjectMVC3.cs to hook up the HomeController's constructor with the MessagingService.
 

Add below line to RegisterServices function.

private static void RegisterServices(IKernel kernel)

{

    kernel.Bind<IMessagingService>().To<MessagingService>();

}


Run the project again.

Isn't it so simple, our Hello World project now utilize Ninject to inject the MessingingService dependency to a Controller.

Unit Test 

Let's get back to our Test project for demo Moq and Unit Test.  Because we will use Moq to setup mock to MessagingSerive, let's install it using NuGet Package Installer.

Right click simpleNinjectDemo.Tests Project and add Moq.

 

MVC 3 + Ninject + Moq + Unit Test Step By Step

see the Reference folder there is Moq dll added

Now open HomeControllerTest.cs in SimpleNinjectDemo.Test project, and then remove the whole About() test, or just comment it out, we will only focus on Index() test.

HomeControllerTest.cs should look like this

using System.Web.Mvc;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using NinjectSimpleDemo.Controllers;

 

namespace SimpleNinjectDemo.Tests.Controllers

{

    [TestClass]

    public class HomeControllerTest

    {

        [TestMethod]

        public void Index()

        {

            // Arrange

            HomeController controller = new HomeController();

 

            // Act

            ViewResult result = controller.Index() as ViewResult;

 

            // Assert

            Assert.AreEqual("Welcome to ASP.NET MVC!", result.ViewBag.Message);

        }

  }

}


If you build the test project now, the compiler will return error message
"'NinjectSimpleDemo.Controllers.HomeController' does not contain a constructor that takes 0 arguments" .  It's time to call Moq for help.

The HomeController now requires an object as a parameter and we will mock one for it.
Add below code to the Arrange section

// Arrange

var expectedResult = "Hello, Unit Test!";

var messagingService = new Mock<IMessagingService>();

messagingService.Setup(m => m.HelloWorld()).Returns(expectedResult);


And then put messagingService.Object as the parameter of HomeController constructor

HomeController controller = new HomeController(messagingService.Object);


Lastly, modify the Assert part like below

// Assert

Assert.AreEqual(expectedResult, result.ViewBag.Message);


Run the Test by right click the class and then choose Run Tests