ASP.NET MVC - Unit Testing



In computer programming, unit testing is a software testing method by which individual units of source code are tested to determine whether they are fit for use. In other words, it is a software development process in which the smallest testable parts of an application, called units, are individually and independently scrutinized for proper operation.

In procedural programming, a unit could be an entire module, but it is more commonly an individual function or procedure. In object-oriented programming, a unit is often an entire interface, such as a class, but could be an individual method.

Unit testing is often automated but it can also be done manually.

Goals of Unit Testing

The primary goal of unit testing is to take the smallest piece of testable software in the application and determine whether it behaves exactly as you expect. Each unit is tested separately before integrating them into modules to test the interfaces between modules.

Let’s take a look at a simple example of unit testing in which we create a new ASP.NET MVC application with Unit Testing.

Step 1 − Open the Visual Studio and click File → New → Project menu option.

A new Project dialog opens.

New Project Dialog

Step 2 − From the left pane, select Templates > Visual C# > Web.

Step 3 − In the middle pane, select ASP.NET Web Application.

Step 4 − Enter the project name ‘MVCUnitTestingDemo’ in the Name field and click Ok to continue. You will see the following dialog which asks you to set the initial content for the ASP.NET project.

MVCUnitTestingDemo

Step 5 − Select the MVC as template and don’t forget to check the Add unit tests checkbox which is at the bottom of dialog. You can also change the test project name as well, but in this example we leave it as is since it is the default name.

Once the project is created by Visual Studio, you will see a number of files and folders displayed in the Solution Explorer window.

Step 6 − You can see that two projects are there in the solution explorer. One is the ASP.NET Web project and the other is the unit testing project.

Web Project

Step 7 − Run this application and you will see the following output.

Run Web Project

As seen in the above screenshot, there are Home, About and Contact buttons on the navigation bar. Let’s select ‘About’ and you will see the following view.

About Select

Let’s select Contact and the following screen pops up.

Contact Select

Now let’s expand the ‘MVCUnitTestingDemo’ project and you will see the HomeController.cs file under the Controllers folder.

HomeController.cs file

The HomeController contains three action methods as shown in the following code.

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCUnitTestingDemo.Controllers {
   public class HomeController : Controller{
      public ActionResult Index(){
         return View();
      } 
		
      public ActionResult About(){
         ViewBag.Message = "Your application description page.";
         return View();
      }
		
      public ActionResult Contact(){
         ViewBag.Message = "Your contact page.";
         return View();
      }
   }
}

Let’s expand the MVCUnitTestingDemo.Tests project and you will see the HomeControllerTest.cs file under the Controllers folder.

MVCUnitTestingDemo.Test

In this HomeControllerTest class, you will see three methods as shown in the following code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using MVCUnitTestingDemo;
using MVCUnitTestingDemo.Controllers;

namespace MVCUnitTestingDemo.Tests.Controllers{
   [TestClass]
   public class HomeControllerTest{
	
      [TestMethod]
      public void Index(){
         // Arrange
         HomeController controller = new HomeController();
         // Act
         ViewResult result = controller.Index() as ViewResult;
         // Assert
         Assert.IsNotNull(result);
      }
		
      [TestMethod]
      public void About(){
         // Arrange
         HomeController controller = new HomeController();
         // Act
         ViewResult result = controller.About() as ViewResult;
         // Assert
         Assert.AreEqual("Your application description page.", result.ViewBag.Message);
      }
		
      [TestMethod]
      public void Contact(){
         // Arrange
         HomeController controller = new HomeController();
         // Act
         ViewResult result = controller.Contact() as ViewResult;
         // Assert
         Assert.IsNotNull(result);
      }
   }
}

These three methods will test whether the Index, About and Contact action methods are working properly. To test these three action methods, go to the Test menu.

Test Menu

Select Run → All Tests to test these action methods.

Action Methods

Now you will see the Test Explorer on the left side in which you can see that all the tests are passed. Let us add one more action method, which will list all the employees. First we need to add an employee class in the Models folder.

Following is the Employee class implementation.

using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;

namespace MVCUnitTestingDemo.Models{
   public class Employee{
      public int ID { get; set; }
      public string Name { get; set; }
      public DateTime JoiningDate { get; set; }
      public int Age { get; set; }
   }
}

We need to add EmployeeController. Right-click on the controller folder in the solution explorer and select Add → Controller.

It will display the Add Scaffold dialog.

Add Scaffold

Select the MVC 5 Controller – Empty option and click ‘Add’ button and the Add Controller dialog will appear.

Set the name to EmployeeController and click ‘Add’ button.

Add Controller EmployeeController

You will see a new C# file ‘EmployeeController.cs’ in the Controllers folder which is open for editing in Visual Studio. Let’s update the EmployeeController using the following code.

using MVCUnitTestingDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;

namespace MVCUnitTestingDemo.Controllers {
   public class EmployeeController : Controller{
      [NonAction]
		
      public List<Employee> GetEmployeeList(){
         return new List<Employee>{
            new Employee{
               ID = 1,
               Name = "Allan",
               JoiningDate = DateTime.Parse(DateTime.Today.ToString()),
               Age = 23
            },
				
            new Employee{
               ID = 2,
               Name = "Carson",
               JoiningDate = DateTime.Parse(DateTime.Today.ToString()),
               Age = 45
            },
				
            new Employee{
               ID = 3,
               Name = "Carson",
               JoiningDate = DateTime.Parse(DateTime.Today.ToString()),
               Age = 37
            },
				
            new Employee{
               ID = 4,
               Name = "Laura",
               JoiningDate = DateTime.Parse(DateTime.Today.ToString()),
               Age = 26
            },
         };
      }
      
      // GET: Employee
      public ActionResult Index(){
         return View();
      }
		
      public ActionResult Employees(){
         var employees = from e in GetEmployeeList()
         orderby e.ID
         select e;
         return View(employees);
      }
   }
}

To add View for Employees action method, right-click on Employees action and select Add View…

Employee Action

You will see the default name for view. Select ‘List’ from the Template dropdown and ‘Employee’ from the Model class dropdown and click Ok.

Now we need to add the link Employees list, let’s open the _layout.cshtml file which is under Views/Shared folder and add the link for employees list below the Contact link.

<li>@Html.ActionLink("Employees List", "Employees", "Employee")</li>

Following is the complete implementation of _layout.cshtml.

<!DOCTYPE html>
<html>
   <head>
      <meta charset = "utf-8" />
      <meta name = "viewport" content = "width = device-width, initial-scale = 1.0">
      <title>@ViewBag.Title - My ASP.NET Application</title>
      @Styles.Render("~/Content/css")
      @Scripts.Render("~/bundles/modernizr")
   </head>
	
   <body>
      <div class = "navbar navbar-inverse navbar-fixed-top">
         <div class = "container">
			
            <div class = "navbar-header">
               <button type = "button" class = "navbar-toggle" datatoggle =
                  "collapse" data-target = ".navbar-collapse">
                  <span class = "icon-bar"></span>
                  <span class = "icon-bar"></span>
                  <span class = "icon-bar"></span>
               </button>
					
               @Html.ActionLink("Application name", "Index", "Home", new
                  { area = "" }, new { @class = "navbar-brand" })
            </div>
				
            <div class = "navbar-collapse collapse">
               <ul class = "nav navbar-nav">
                  <li>@Html.ActionLink("Home", "Index", "Home")</li>
                  <li>@Html.ActionLink("About", "About", "Home")</li>
                  <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                  <li>@Html.ActionLink("Employees List", "Employees", "Employee")</li>
               </ul>
					
               @Html.Partial("_LoginPartial")
            </div>
				
         </div>
			
      </div>
		
      <div class = "container body-content">
         @RenderBody()
         <hr />
         <footer>
            <p>© @DateTime.Now.Year - My ASP.NET Application</p>
         </footer>
      </div>
		
      @Scripts.Render("~/bundles/jquery")
      @Scripts.Render("~/bundles/bootstrap")
      @RenderSection("scripts", required: false)
		
   </body>
</html>

To test Employees action method from the Employee controller, we need to add another test method in our unit testing project. Following s the EmployeeControllerTest class in which we will test the Employees action method.

[TestClass]
public class EmployeeControllerTest{
   [TestMethod]
   public void Employees(){
      // Arrange
      EmployeeController controller = new EmployeeController();
		
      // Act
      ViewResult result = controller.Index() as ViewResult;
		
      // Assert
      Assert.IsNotNull(result);
   }
}

Select Run → All Tests from the Test menu to test these action methods.

Employee Test Method

You can see that the Employees test method is also passed now. When you run the application, you will see the following output.

Click ‘Employees List’ option in the navigation bar and you will see the list of employees.

Employee List
Advertisements