Here in this article I will explain what Unit Testing is in MVC projects. When MVC was launched Unit Testing was promoted as one of the biggest advantages of using MVC when developing business applications. If your business application is growing day by day then it becomes challenging to keep the application on track. Then Unit Testing plays a vital role in the success of your business application.
Now we will learn Unit Testing step-by-step. Here I will create a MVC application first with Entity Framework to do CRUD operations.
Open Visual Studio 2012 -> New -> Project.

Now your solution will look as in the following.
Now right-click on the Model Folder then select Add -> ADO.NET Entity Data Model.






Here we will use the repository pattern so right-click on the Model Folder then select Add New Interface.
Define the following method in IEmployeeRepository.cs.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace UnitTestingAppInMVC.Models
- {
- public interface IEmployeeRepository : IDisposable
- {
- IEnumerable<Employee> GetAllEmployee();
- Employee GetEmployeeByID(int emp_ID);
- void InsertEmployee(Employee emp);
- void DeleteEmployee(int emp_ID);
- void UpdateEmployee(Employee emp);
- int Save();
- }
- }

- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Linq;
- using System.Web;
- namespace UnitTestingAppInMVC.Models
- {
- public class EmployeeRepository: IEmployeeRepository,
- IDisposable
- {
- EmployeeManagementEntities context = new EmployeeManagementEntities();
- public IEnumerable < Employee > GetAllEmployee()
- {
- return context.Employee.ToList();
- }
- public Employee GetEmployeeByID(int id)
- {
- return context.Employee.Find(id);
- }
- public void InsertEmployee(Employee emp)
- {
- context.Employee.Add(emp);
- }
- public void DeleteEmployee(int emp_ID)
- {
- Employee emp = context.Employee.Find(emp_ID);
- context.Employee.Remove(emp);
- }
- public void UpdateEmployee(Employee emp)
- {
- context.Entry(emp).State = EntityState.Modified;
- }
- public int Save()
- {
- return context.SaveChanges();
- }
- private bool disposed = false;
- protected virtual void Dispose(bool disposing)
- {
- if (!this.disposed)
- {
- if (disposing)
- {
- context.Dispose();
- }
- }
- this.disposed = true;
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- }
- }

- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using UnitTestingAppInMVC.Models;
- using PagedList;
- using System.Data;
- namespace UnitTestingAppInMVC.Controllers
- {
- public class EmployeeController: Controller
- {
- IEmployeeRepository employeeRepository;
- public EmployeeController(): this(new EmployeeRepository()) {}
- public EmployeeController(IEmployeeRepository repository)
- {
- employeeRepository = repository;
- }
- public ViewResult Index(string sortOrder, string currentFilter, string searchString, int ? page)
- {
- ViewData["ControllerName"] = this.ToString();
- ViewBag.CurrentSort = sortOrder;
- ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Emp_ID" : "";
- if (searchString != null)
- {
- page = 1;
- } else {
- searchString = currentFilter;
- }
- ViewBag.CurrentFilter = searchString;
- var employees = from s in employeeRepository.GetAllEmployee()
- select s;
- if (!String.IsNullOrEmpty(searchString))
- {
- employees = employees.Where(s = > s.Name.ToUpper().Contains(searchString.ToUpper()) || s.Name.ToUpper().Contains(searchString.ToUpper()));
- }
- switch (sortOrder) {
- case "Emp ID":
- employees = employees.OrderByDescending(s = > s.Emp_ID);
- break;
- case "Name":
- employees = employees.OrderBy(s = > s.Name);
- break;
- case "State":
- employees = employees.OrderByDescending(s = > s.State);
- break;
- case "Country":
- employees = employees.OrderByDescending(s = > s.Country);
- break;
- default:
- employees = employees.OrderBy(s = > s.Emp_ID);
- break;
- }
- int pageSize = 5;
- int pageNumber = (page ? ? 1);
- return View("Index", employees.ToPagedList(pageNumber, pageSize));
- }
- //
- // GET: /Employee/Details/5
- public ViewResult Details(int id)
- {
- Employee emp = employeeRepository.GetEmployeeByID(id);
- return View(emp);
- }
- //
- // GET: /Employee/Create
- public ActionResult Create()
- {
- return View("Create");
- }
- //
- // POST: /Employee/Create
- [HttpPost]
- public ActionResult Create(Employee emp)
- {
- try {
- if (ModelState.IsValid)
- {
- employeeRepository.InsertEmployee(emp);
- employeeRepository.Save();
- return RedirectToAction("Index");
- }
- }
- catch (Exception ex)
- {
- ModelState.AddModelError(string.Empty, "Some Error Occured.");
- }
- return View("Create", emp);
- }
- //
- // GET: /Employee/Edit/5
- public ActionResult Edit(int id)
- {
- Employee emp = employeeRepository.GetEmployeeByID(id);
- return View(emp);
- }
- //
- // POST: /Employee/Edit/5
- [HttpPost]
- [ValidateAntiForgeryToken]
- public ActionResult Edit(Employee emp)
- {
- try
- {
- if (ModelState.IsValid)
- {
- employeeRepository.UpdateEmployee(emp);
- employeeRepository.Save();
- return RedirectToAction("Index");
- }
- }
- catch (Exception ex)
- {
- ModelState.AddModelError(string.Empty, "Some error Occured.");
- }
- return View(emp);
- }
- //
- // GET: /employee/Delete/5
- public ActionResult Delete(bool ? saveChangesError = false, int id = 0)
- {
- if (saveChangesError.GetValueOrDefault())
- {
- ViewBag.ErrorMessage = "Some Error Occured.";
- }
- Employee emp = employeeRepository.GetEmployeeByID(id);
- return View(emp);
- }
- //
- // POST: /Employee/Delete/5
- [HttpPost]
- [ValidateAntiForgeryToken]
- public ActionResult Delete(int id)
- {
- try
- {
- Employee emp = employeeRepository.GetEmployeeByID(id);
- employeeRepository.DeleteEmployee(id);
- employeeRepository.Save();
- }
- catch (Exception ex)
- {
- return RedirectToAction("Delete", new
- {
- id = id, saveChangesError = true
- });
- }
- return RedirectToAction("Index");
- }
- protected override void Dispose(bool disposing)
- {
- employeeRepository.Dispose();
- base.Dispose(disposing);
- }
- }
- }
Unit Testing
Now to work on the Unit Testing part.
In UnitTestingAppInMVC.Tests add a folder named Model. Right-click on the Model Folder then select Add New Class InMemoryEmployeeRepository.cs.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using UnitTestingAppInMVC.Models;
- namespace UnitTestingAppInMVC.Tests.Models
- {
- class InMemoryEmployeeRepository: IEmployeeRepository
- {
- private List < Employee > _db = new List < Employee > ();
- public Exception ExceptionToThrow
- {
- get;
- set;
- }
- public IEnumerable < Employee > GetAllEmployee()
- {
- return _db.ToList();
- }
- public Employee GetEmployeeByID(int id)
- {
- return _db.FirstOrDefault(d = > d.Emp_ID == id);
- }
- public void InsertEmployee(Employee employeeToCreate)
- {
- _db.Add(employeeToCreate);
- }
- public void DeleteEmployee(int id)
- {
- _db.Remove(GetEmployeeByID(id));
- }
- public void UpdateEmployee(Employee employeeToUpdate)
- {
- foreach(Employee employee in _db)
- {
- if (employee.Emp_ID == employeeToUpdate.Emp_ID)
- {
- _db.Remove(employee);
- _db.Add(employeeToUpdate);
- break;
- }
- }
- }
- public int Save()
- {
- return 1;
- }
- private bool disposed = false;
- protected virtual void Dispose(bool disposing)
- {
- if (!this.disposed)
- {
- if (disposing)
- {
- //Dispose Object Here
- }
- }
- this.disposed = true;
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- }
- }
Add A New Controller class
Now add a new Controller class EmployeeControllerTest.cs.
- using Microsoft.VisualStudio.TestTools.UnitTesting;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Security.Principal;
- using System.Text;
- using System.Threading.Tasks;
- using System.Web;
- using System.Web.Mvc;
- using System.Web.Routing;
- using UnitTestingAppInMVC.Controllers;
- using UnitTestingAppInMVC.Models;
- using UnitTestingAppInMVC.Tests.Models;
- namespace UnitTestingAppInMVC.Tests.Controllers
- {
- [TestClass]
- public class EmployeeControllerTest
- {
- /// <summary>
- /// This method used for index view
- /// </summary>
- [TestMethod]
- public void IndexView()
- {
- var empcontroller = GetEmployeeController(new InMemoryEmployeeRepository());
- ViewResult result = empcontroller.Index(null, null, null, null);
- Assert.AreEqual("Index", result.ViewName);
- Assert.IsInstanceOfType(result, typeof(ViewResult));
- }
- /// <summary>
- /// This method used to get employee controller
- /// </summary>
- /// <param name="repository"></param>
- /// <returns></returns>
- private static EmployeeController GetEmployeeController(IEmployeeRepository emprepository)
- {
- EmployeeController empcontroller = new EmployeeController(emprepository);
- empcontroller.ControllerContext = new ControllerContext()
- {
- Controller = empcontroller,
- RequestContext = new RequestContext(new MockHttpContext(), new RouteData())
- };
- return empcontroller;
- }
- /// <summary>
- /// This method used to get all employye listing
- /// </summary>
- [TestMethod]
- public void GetAllEmployeeFromRepository()
- {
- // Arrange
- Employee employee1 = GetEmployeeName(1, "Rahul Saxena", "[email protected]", "Software Developer", "Noida", "Uttar Pradesh", "India");
- Employee employee2 = GetEmployeeName(2, "Abhishek Saxena", "[email protected]", "Tester", "Saharanpur", "Uttar Pradesh", "India");
- InMemoryEmployeeRepository emprepository = new InMemoryEmployeeRepository();
- emprepository.InsertEmployee(employee1);
- emprepository.InsertEmployee(employee2);
- var controller = GetEmployeeController(emprepository);
- var result = controller.Index(null, null, null, null);
- var datamodel = (IEnumerable < Employee > ) result.ViewData.Model;
- CollectionAssert.Contains(datamodel.ToList(), employee1);
- CollectionAssert.Contains(datamodel.ToList(), employee2);
- }
- /// <summary>
- /// This method used to get emp name
- /// </summary>
- /// <param name="Emp_ID"></param>
- /// <param name="Name"></param>
- /// <param name="Email"></param>
- /// <param name="Designation"></param>
- /// <param name="City"></param>
- /// <param name="State"></param>
- /// <param name="Country"></param>
- /// <returns></returns>
- Employee GetEmployeeName(int Emp_ID, string Name, string Email, string Designation, string City, string State, string Country)
- {
- return new Employee
- {
- Emp_ID = Emp_ID,
- Name = Name,
- Email = Email,
- Designation = Designation,
- City = City,
- State = State,
- Country = Country
- };
- }
- /// <summary>
- /// This test method used to post employee
- /// </summary>
- [TestMethod]
- public void Create_PostEmployeeInRepository()
- {
- InMemoryEmployeeRepository emprepository = new InMemoryEmployeeRepository();
- EmployeeController empcontroller = GetEmployeeController(emprepository);
- Employee employee = GetEmployeeID();
- empcontroller.Create(employee);
- IEnumerable < Employee > employees = emprepository.GetAllEmployee();
- Assert.IsTrue(employees.Contains(employee));
- }
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- Employee GetEmployeeID()
- {
- return GetEmployeeName(1, "Rahul Saxena", "[email protected]", "Software Developer", "Noida", "Uttar Pradesh", "India");
- }
- /// <summary>
- ///
- /// </summary>
- [TestMethod]
- public void Create_PostRedirectOnSuccess()
- {
- EmployeeController controller = GetEmployeeController(new InMemoryEmployeeRepository());
- Employee model = GetEmployeeID();
- var result = (RedirectToRouteResult) controller.Create(model);
- Assert.AreEqual("Index", result.RouteValues["action"]);
- }
- /// <summary>
- ///
- /// </summary>
- [TestMethod]
- public void ViewIsNotValid()
- {
- EmployeeController empcontroller = GetEmployeeController(new InMemoryEmployeeRepository());
- empcontroller.ModelState.AddModelError("", "mock error message");
- Employee model = GetEmployeeName(1, "", "", "", "", "", "");
- var result = (ViewResult) empcontroller.Create(model);
- Assert.AreEqual("Create", result.ViewName);
- }
- }
- public class MockHttpContext: HttpContextBase
- {
- private readonly IPrincipal _user = new GenericPrincipal(new GenericIdentity("someUser"), null /* roles */ );
- public override IPrincipal User
- {
- get
- {
- return _user;
- }
- set
- {
- base.User = value;
- }
- }
- }
- }



Anu VPosted Oct 28, 2015, 7:15 AM
Thanks
Rahul Kumar SaxenaPosted Jun 25, 2015, 4:30 AM
Thanks Bruno P?terson
Bruno PétersonPosted Jun 18, 2015, 3:40 PM
Cool
Rahul Kumar SaxenaPosted Apr 23, 2015, 2:13 PM
Thanks Karthik Muthu Karuppan
Karthik Muthu KaruppanPosted Apr 23, 2015, 11:21 AM
nice
Rahul Kumar SaxenaPosted Apr 21, 2015, 10:37 PM
Thanks. Krishnanand Sivaraj
Rahul Kumar SaxenaPosted Apr 21, 2015, 10:37 PM
Thanks. sreenivasa k
Krishnanand SivarajPosted Apr 21, 2015, 10:08 PM
Thanks for sharing
sreenivasa kPosted Apr 21, 2015, 3:45 PM
good article
Rahul Kumar SaxenaPosted Apr 21, 2015, 12:52 PM
thanks sahil dashora
Rahul Kumar SaxenaPosted Apr 21, 2015, 12:52 PM
Thanks Abhishek Jaiswal
Rahul Kumar SaxenaPosted Apr 21, 2015, 12:43 PM
Thanks Santhakumar Munuswamy
Shaili DashoraPosted Apr 21, 2015, 11:06 AM
Nice one...
Abhishek JaiswalPosted Apr 21, 2015, 9:46 AM
Good Information! Keep it up! :) :)
Santhakumar MunuswamyPosted Apr 21, 2015, 9:44 AM
Thanks Rahul Saxena
Santhakumar MunuswamyPosted Apr 21, 2015, 9:44 AM
Excellent work
Rahul Kumar SaxenaPosted Apr 21, 2015, 8:17 AM
Thanks Manish Kumar Choudhary...
Manish Kumar ChoudharyPosted Apr 21, 2015, 7:12 AM
Nice one.
Rahul Kumar SaxenaPosted Apr 21, 2015, 6:08 AM
Thanks Nitin Tyagi...
NitinPosted Apr 21, 2015, 5:50 AM
excellent work Rahul Saxena