Click here to Skip to main content
15,441,149 members
Articles / DevOps / Unit Testing
Posted 23 Apr 2014


98 bookmarked

MVC Unit Testing Unleashed

Rate me:
Please Sign up or sign in to vote.
4.79/5 (95 votes)
14 May 2014CPOL9 min read
In this article we will learn how to perform Unit Testing in Asp.Net MVC


We are going to talk about MVC unit testing, so it’s must to have at least basic idea about MVC.

You should know,

  • What is the purpose of MVC?
  • How MVC Works?
  • What are different ways of passing data between different layers of MVC application?
  • How to perform navigation in MVC?

Image 1

If you are new to MVC, please try to find answers for above questions first. Click here for our learn MVC step by step series.

What we will learn?


As you can see, I have broken down this article into many sub topics. Article is written considering every reader is completely new to Unit Testing. If you know any of the sub topic listed above, you can skip that and move to next sub topic J.

Basics of Unit Testing

When we hear the word Asp.Net MVC mainly two things comes to our mind.

  • Full control over HTML
  • Easy to Unit Test.

If you are already familiar with basics of unit testing then directly start with “Way towards MVC Unit Testing”.

What is Unit Testing?

Very basic definition will be, testing of every smallest testable block of a code in an automated manner.

Still confused?

Let me make it simpler.

Image 2

  • In real world every application comprises of many modules. For instance consider a simple E-Commerce application may comprises of Inventory Module, Customer management Module, Order module etc.
  • Every Module is made of using more than one classes.
  • Every class exposes many functionalities in the form of functions.

In Unit Testing we test these functions individually in an automated manner.

What exactly mean by “Automated Manner”?

We will write one more code which will do the testing of our other code (testing of the result of a function).

What is the importance of Unit Testing?

To understand this, answer following question without using any tool or application. “What is the result of 996*965/5?”

3 more questions

  • Do you think your answer is correct?
  • If yes, how much time you took to get the result?
  • Can you reuse the calculation process (which was performed in your mind), if the figure in the operation get changed?

    Now just replace the manual work performed inside your mind with a calculator.

  • Now you will be 100% sure about the result.
  • Answer will be quick.
  • Reuse the same calculator for another calculation.

    Automation makes things more accurate, faster and reusable.

When we write automatic unit test cases for our code, it will become a proof which proves that our code is working. The best part is whenever we make any changes in the code, we just rerun the previously written unit test case and confirms that previous things are not broken.

Basic example of Unit Testing

Step 1. Create a class library which need to be tested with following code block.

public class CustomMaths
    public int Add(int num1,int num2)
        return Number1 + Number2;

Step 2. Create Unit Testing Project as Follows

Image 3

Step 3. Add reference of previous class library to this newly created project

Step 4. Create Test class as follows

public class TestMathsClass
    public void TestAdd()
        CustomMaths maths = new CustomMaths();

        int result = maths.Add(6, 5);

        Assert.AreEqual<int>(11, result);

Explanation – As you can see Unit Testing follows simple three steps.

  • Arrange - Create objects and prepare everything needed to test functionality
  • Act – Execute and get the output
  • Assert – Compare final output with expected Output

Step 5. Build your solution and open test explorer window from Test > Windows > Test Explorer

Step 6. Right click Test cases and say Run Selected Tests.

Image 4

Note: In the example we are using hard coded values (5 and 6) for testing but in real life scenario we will not use hard coded values rather will use some kind of data source like excel or database for input parameters and return value.

Way towards MVC Unit Testing

Now you know what is unit testing and how it works. Then it’s time to understand how unit test works in MVC.

What are different types of logic we write?

Normally when we say “Logic” only thing which we think about is “Business Logic”. In real world applications we end up with writing many different types of logics.

Image 5

Business Logic

Logic related to business. Example Tax calculation, order processing, conversion (from excel to pdf) etc.

Data Transformation Logic

We have Date of Birth stored in our database and we want to display age in the page. Logic which converts our business data to a data specific to view is called Data Transformation logic.

Presentation Logic

Logic which will change the presentation in the page (or any output which end user going to get) based on some value in database (or any other value), is called Presentation Logic. Example – If employee salary is greater than 50k show him in blue color or else show him in green color.

User Interaction logic

Logic will handle different user interactions like clicking of some control is called as User Interaction Logic.

Database Logic

Logic which will handle the database specific code is called Database logic. Example of such kind of logic is executing a store procedure.

Difficulties in testing traditional Web Forms apps.

The best we can do while working with traditional Web Form application is, break it into 3 (or may be more) Layer. Each layer will perform some specific logic. In this case Business logic and Database logic will be written as two separate layer (called Business layer and database layer respectively). Unit testing of these two layers will be easy because they will be written as simple class libraries (with set of classes and functions) and thus two layers can be tested in the same way we did above.

Here the problem is,

  • UI is tightly coupled to code behind.
  • User Interaction logic, Presentation Logic and Data Transformation logic will be written inside code behind.
  • Unit testing of code behind is not possible because code behind contains Event handlers and invoking event handler as a function will be very difficult task because it mostly have two parameters called “object sender” and “EventArgs e” which cannot be generated programmatically

Image 6

Thus Unit Testing of User Interaction Logic, Data Transformation logic and Presentation logic will not be possible.

Testing in MVC?

Basic components of Asp.Net MVC are,

  • Model – Business data and Business logic.
  • View – Aspx or Razor (or may be some user defined) UI contain some visual elements.
  • Controller – Handles the user Interaction logic.

1. User Interaction Logic testing

As we know,

  • Every request in Asp.Net MVC go via Controller.
• Controller contain the user interaction logic.
• Controller is not tightly coupled with View

Image 7

Image 8 Thus testing of User Interaction logic is possible in Asp.Net MVC.

Code Demonstration

Asp.Net MVC User interaction testing or Controller testing consist of

  • Testing for ViewResult
  • Testing of ViewData/ ViewBag
  • Testing For RedirectResult

Demo 1 – Testing for ViewResult

Let’s assume we have following action method.

//Action Method
public ActionResult GetView(int id)
    if (id == 0)
        return View("View2");
        return View("View1");

Our task is to create a test method which will confirm whether action method generates proper ViewResult or not.

//Test Cases
public void TestForViewWithValue0()
    TestingController t = new TestingController();

    ViewResult r = t.GetView(0) as ViewResult;
    Assert.AreEqual("View2", r.ViewName);

public void TestForViewWithValueOtherThanZero()
    TestingController t = new TestingController();

    ViewResult r = t.GetView(1) as ViewResult;
    Assert.AreEqual("View1", r.ViewName);

Demo 2 – Testing for ViewData/ ViewBag

Let’s assume we have following action method.

//Action Method
public ActionResult Action2()
    ViewData["Name"] = "SomeName";
    return View();

Our task is to create a test method which will confirm whether action method generates proper ViewData or not.

//Test Cases
public void TestForViewData()
    TestingController t = new TestingController();

    ViewResult r = t.Action2() as ViewResult;

    Assert.AreEqual("Sukesh", r.ViewData["Name"]);


Demo 3 – Testing for Redirection

Let’s assume we have following action method.

//Action Method
public ActionResult Details(int Id)
    if (Id < 0)
        return RedirectToAction("Index","SomeElse");

    return View("Details");


Our task is to create a test method which will confirm whether action method is redirecting to proper location or not.

//Test Cases
public void TestDetailsForRedirect()
    TestingController controller = new TestingController();
    var result = controller.Details(-1) as RedirectToRouteResult;
    Assert.AreEqual("Index", result.RouteValues["action"]);
    Assert.AreEqual("SomeElse", result.RouteValues["controller"]);
public void TestDetailsForViewResult()
    TestingController controller = new TestingController();
    ViewResult result1 = (ViewResult)controller.Details(2);
    Assert.AreEqual("Details", result1.ViewName);

Note: Testing steps won’t get change here. Once the test cases are created simply build it and from test explorer windows execute the test cases as shown in “Basic example of Unit Testing”.

2. Business Logic

As we said before Business logic and Business data is a part of Model in Asp.Net MVC.
Business logic will be implemented as a simple .Net class with couple of functions. We can easily unit test it in the same way we did in “Basic example of Unit Testing”.

Image 9

3. Database Logic

Image 10

In Asp.Net MVC talk nowhere clearly spoken about the database layer. We
usually make it as a separate layer which will be accessed via Business Layer.
Again at the end of the day it’s going to be a single class with couple of function.
Unit testing will be same like above.

4. Data transformation Logic and Presentation Logic.

This is where all voice go down. These two logic decides what data need to
be displayed and how.
They are directly associated with the view. If we write such logic in View unit testing
will not be possible.

Image 11

Let’s look at an application which contain Data Transformation logic and Presentation logic in the view itself.

Image 12 What we have?
  • Employee Model
public class Employee
    public string EmployeeName { get; set; }
    public string Address { get; set; }
    public DateTime DateOfBirth { get; set; }
    public int Salary { get; set; }
  • Employee Controller
public class EmployeeController : Controller
    public ActionResult Show()
        Employee e = GetEmployee();
        return View(e);
  • Employee Show View (Show.cshtml)
    Employee Detail<br />
    Employee Name : @Model.EmployeeName<br />
    Address : @Model.Address

    <br />
        int age = DateTime.Now.Year - Model.DateOfBirth.Year;
        if (Model.DateOfBirth > DateTime.Now.AddYears(-age))
    Age : @age

    <br />
    @if (Model.Salary > 20000)
        <span style="color: red">Salary : @Model.Salary</span>
        <span style="color: green">Salary : @Model.Salary</span>

As you can see, we are

  • Converting date of birth to age and then displaying it - data transformation logic.
  • Based on the salary color of the display text is changing – presentation logic.

Such kind of tightly coupling between UI Design, Presentation logic and Data transformation logic becomes an obstacle for complete unit testing.

What’s the solution?

Solution will be logical more than technical.

We will introduce one more layer between Model and View and call it ViewModel.

Model will be identified as data and logic related to business whereas ViewModel will be identified as data and logic related to View.

There will not be any direct connection between Model and the view. View will always connect to ViewModel which will contain

  1. Reference to the Model
  2. Data Transformation logic as per requirement in the View.
  3. Presentation logic based on the View requirement.

So, the first step will be creating Employee View Model as follows.

public class EmployeeVM
    public Employee emp { get; set; }
    public EmployeeVM(Employee e1)
        emp = e1;
    public int Age
            int age = DateTime.Now.Year - emp.DateOfBirth.Year;
            if (emp.DateOfBirth > DateTime.Now.AddYears(-age))
            return age;

    public string SalaryColor
                return "red";
                return "green";

Second step will be making view a strongly typed view of ViewModel class instead of Model as follows.

    Employee Detail<br />
    Employee Name : @Model.emp.EmployeeName<br />
    Address : @Model.emp.Address <br />
    Age : @Model.Age
        <br />
    <span style="color:@Model.SalaryColor">Salary : @Model.emp.Salary</span>
Here we are. View Model is simply a class with two properties which can be
tested using simple unit testing logic. That means our presentation logic and data
transformation logic is now testable.

Image 13

See the following video on View Model in ASP.NET MVC: -

Image 14


MVC is an architectural pattern meant for solving UI level problems. We had just saw how we separate our UI from logic completely and makes our each and every logical code a testable code.Keep coding, Keep learning and Keep sharing.

Don’t forget to vote and comment.

For technical trainings on various topics like WCF, MVC, Business Intelligence, Design Patterns, WPF,

TFS and Basic fundamentals feel free to contact or visit

For more stuff like this click here. Subscribe to article updates or follow at twitter @SukeshMarla

See 600+ above FAQ questions and answers in .NET, C#, ASP.NET, SQL, WCF, WPF, WWF, SharePoint, Design patterns, UML etc.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Written By
Founder Just Compile
India India
Learning is fun but teaching is awesome.

Who I am? Trainer + consultant + Developer/Architect + Director of Just Compile

My Company - Just Compile

I can be seen in, @sukeshmarla or Facebook

Comments and Discussions

QuestionGood Articles Pin
Laiju k2-Feb-18 19:59
professionalLaiju k2-Feb-18 19:59 
QuestionArticle text Pin
ShahYatin20-Mar-17 17:25
MemberShahYatin20-Mar-17 17:25 
PraiseInformative article Pin
jaylala26-Feb-17 19:32
Memberjaylala26-Feb-17 19:32 
PraiseNice Article Pin
Kiran Viradiya18-Oct-16 22:14
MemberKiran Viradiya18-Oct-16 22:14 
QuestionHow should we view the test outputs? Pin
Member 1262440014-Jul-16 17:07
MemberMember 1262440014-Jul-16 17:07 
Questiongreat Pin
zekikaya12-Apr-16 21:27
Memberzekikaya12-Apr-16 21:27 
AnswerRe: great Pin
Marla Sukesh14-Apr-16 20:15
professional Marla Sukesh14-Apr-16 20:15 
Suggestionbug Pin
Member 939404115-Mar-16 19:41
MemberMember 939404115-Mar-16 19:41 
GeneralRe: bug Pin
Marla Sukesh14-Apr-16 20:34
professional Marla Sukesh14-Apr-16 20:34 
Questionthanks very very Pin
Blue.Tian27-Oct-15 3:21
MemberBlue.Tian27-Oct-15 3:21 
AnswerRe: thanks very very Pin
Marla Sukesh14-Apr-16 20:35
professional Marla Sukesh14-Apr-16 20:35 
Questionnice article for starters, but... Pin
Ibrahim ben Salah15-Sep-15 11:38
MemberIbrahim ben Salah15-Sep-15 11:38 
QuestionThanks Pin
Mohammed Nhari8-Sep-15 6:27
MemberMohammed Nhari8-Sep-15 6:27 
AnswerRe: Thanks Pin
Marla Sukesh25-Sep-15 8:27
professional Marla Sukesh25-Sep-15 8:27 
QuestionSimple, good article, easily understood. However... Pin
youngtexas18-Aug-15 12:30
Memberyoungtexas18-Aug-15 12:30 
"Simple_Unit_Test" is my first UNIT Test project - help me understand the unit testing concept and how to do it in the simplest way.

However, the other two projects are not self-contained (web.config set to form authentication but lack related files. Have to set up local database, too). They do not have unit test project attached and demonstrated.

Deserve a solid 4!!
GeneralThanks :) Pin
Adil S15-May-15 23:07
MemberAdil S15-May-15 23:07 
GeneralMy vote of 4 Pin
JM Pironneau27-Oct-14 0:54
professionalJM Pironneau27-Oct-14 0:54 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun8-Oct-14 18:47
MemberHumayun Kabir Mamun8-Oct-14 18:47 
GeneralMy vote of 5 Pin
Alexandra Christina16-Jul-14 11:27
MemberAlexandra Christina16-Jul-14 11:27 
GeneralRe: My vote of 5 Pin
Marla Sukesh20-Jul-14 4:46
professional Marla Sukesh20-Jul-14 4:46 
GeneralMy vote of 5 Pin
JasonMacD15-May-14 6:26
MemberJasonMacD15-May-14 6:26 
GeneralRe: My vote of 5 Pin
Marla Sukesh15-May-14 9:44
professional Marla Sukesh15-May-14 9:44 
QuestionUnit testing Private method Pin
JustLikeSummer15-May-14 3:20
MemberJustLikeSummer15-May-14 3:20 
AnswerRe: Unit testing Private method Pin
axy10815-May-14 10:34
professionalaxy10815-May-14 10:34 
GeneralRe: Unit testing Private method Pin
JustLikeSummer29-May-14 1:33
MemberJustLikeSummer29-May-14 1:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.