javascript
Brief description  about Online courses   join in Online courses
OR

Unit Testing ASP.NET MVC applications

Dinesh  Tantri
Dinesh Tantri
Software Testing

ASP.NET MVC
Model-View-Controller (MVC) is a design pattern that separates a web application into three layers: model, view and controller. Model refers to  the data layer; usually it's the layer that interacts directly the data. Basically it's a layer that  talks to the database. View, on the other hand, is the layer that manages the presentation. The presentation layer here can be anything: it can be a form, or HTML, or XML or any other presentation layout. The controller manages the interaction between the model and the view; it's the brain of the application.

One reason why MVC design pattern is so popular over the years, is because it encourages the separation of concern, namely, different types of functionalities are encoded in different modules. MVC differs from the traditional ASP.NET Webform in that   it's easier to change layers. Take for examples if your application needs to run on both web and mobile phone, you don't have to rewrite the whole application; you just have to change the presentation layer, namely the view and keep the controller and model layer intact. MVC also encourages unit testing and promotes a more modular approach to web development. No wonder it generated much excitement when Microsoft announced the ASP.NET MVC project.
•  Unit Testing and AAA Syntax
Everyone has heard about unit testing, and everyone knows by heart that unit testing is important. But the fact is that not many developers actually do it in their production code. Such a wide gap between theoretical understanding and practical doing is indeed astounding, and depressing.

The gap can be attributed partly to the way unit testing is presented in the textbooks and the way unit test that need to be done in the real world. The unit tests, in books, or in blogs, or in tutorials are often applied on simple or trivial examples. But in the real world, code is often messy, different concerns are hopelessly tangled together, and it's often untestable because it has too many fragile dependencies. So when a novice, after reading an introductory test-driven development(TDD) book wants to apply unit test in his code, he will often find that he doesn't know how to deal it and how to write test.

Mocks and stubs are artifacts that we introduce to  workaround the external dependencies problems. The idea is that instead of really calling the external modules that rely on your indeterminate, lousy internet connection, you are fakingthe calls and returning a pre-determined objects. So you are using mocks and stubs to make sure that  your method receives a pre-determined input from external modules and at the end of the test, you make sure that proper external dependencies are invoked.

AAA syntax stands for Arrange, Act and Assert. First you arrange, i.e., setup your test, then you act, i.e., call the method under test, and finally assert,i.e., verify that the output is correct, or to check that specific methods, with correct parameters are called. It performs the same function of mocks.

Personally I prefer AAA syntax over the traditional mocks and stubs, because it's simpler to understand and shorter to write.
 
•  Separation of Test Concern
Separation of concern is a well-known design pattern in software development. What is less well-known, but no less equally utilized is the separation of test concern.

To make things easier, and maybe for organizational purpose, developers who write tests will often structure their test code in parallel with their production code. This kind of parallel setup is great for testing and debugging purpose. However, a complete separation of testing layers is not possible without mocking and stubbing.

The concept of unit testing is to test the code in isolation. But our code can never be truly isolation from one another, so there is always a possibility of an innocuous change in other layers will break your test code. Not that your code is wrong, though, but just that the external dependencies return a value that you don't expect, and hence create a false positive.

The whole idea of mocks and stubs, and AAA syntax, is to make sure that you can test what you want to test, that your test results won't be influenced by what's going on in other layers.  
 
•  A RedditClone Application
Here is a simple Reddit clone application, RedditClone. It has little or no HTML design, and the missing of key features ( such as vote up/down, karma system) are glaring. But I think this application is enough demonstrate how to unit test an ASP.NET MVC application using AAA syntax. Here is a screenshot of the

•  Model classes
The model class has the following repository classes:
public class RedditMembershipProvider : SqlMembershipProvider
{
}
public class ItemFactory
{
}<span class="alt" style="padding-left: 15px; display: block; "><br></span>

Basically, both RedditMembershipProvider and ItemFactory are the classes that deal with the databases directly. They are where all the ORM logics and business rules will reside in. As far the controllers are concerned, it has to deal with those classes, instead of messing with the ORMs and SQL queries themselves.
 •  Controller classes
The controller classes consist of the following controllers.
public class AccountController : Controller
{
}
public class ItemController : Controller
{
}<span class="alt" style="padding-left: 15px; display: block; "><br></span>

Note that they are just a direct map of their underlying model classes.
 
•  Unit Testing Model
Unit testing the model is the easiest of all; one just has to access a test database ( with properly populated initial data, of course) to test the Model classes logic. There are no mocks involved, because there are nothing to mock anyway. Take for example, the following two methods test whether the function ValidateUser is really returning true if the username and password match, or return false if the username and password don't match.
 
•  Unit Testing Controller
Controller, on the other hand, is a bit more difficult to test. The reason for this is that it is dependent on the model as the input, thus it is best if we could control the model's output  directly to really test the controller logic, instead of have to calibrate the input to the model so that the model returns the desired output, so that the controller's action could be properly tested.
Let's assume that for AccountController, we have the following rules
1.    If login successful, authentication cookies should be set, and the page should be redirected to Item/Main method.
2.    If the login fails, then the same page should be displayed, along with the error message
3.    Due to a bug in the underlying ORM, one cannot call the data layer if the username is empty

Let's see how one can write the tests using Typemock.

The first thing to note is that the actions of controller requires output from Model, in this case, the output of
AccountController.Provider.ValidateUser(string username, stringpassword)<span class="alt" style="padding-left: 15px; display: block; "><br></span>

This, in return, would be dependent on the database content, so we should mock away this dependencies, and fake the appropriate returns to test the controller.

Write your comment now