Last post, I introduced the use of Moq framework to code unit tests in .NET applications. Today, I’ll use Moq to test my ASP.NET MVC controllers.
One of the key benefits of ASP.NET MVC is the facility to set up automated tests and use methodologies such as TDD (Test-Driven Development). Using the Red-Green-Refactor mantra, we can create testable ASP.NET MVC controllers and benefit from the use of TDD. So, let’s start.
In this post, we will develop part of a sport store web site responsible for managing products through CRUD operations. First of all, I will create a new ASP.NET MVC Empty Application and a Test Project in Visual Studio 2010. Next, I will create ProductController.cs, responsible for handling requests from all CRUD operations that we are going to provide. Right now, our controller looks like the code below.
The first thing we nedd is a List view where adminitrators can see all existing products, manage products from the list and add new products to the application. For now, we know that we need to pass all products to the view. It is time to write our first test case which demonstrates that behaviour. After some work, here is my test for List operation.
Notice that after writing my test, two new classes appeared: Product and IProductRepository. In addition to that, we added a dependency between ProductController and IProductRepository. What we are doing here is designing our code while writing tests, which means that we are creating testable code. In the test above, we are saying that FindAll method will Returns the list we’ve created with four products and verifying the those products where passed to the view. That simple!
Now that we have a test, let’s run it to see if it pass. Unfortunately, it failed because we did not wrote the implementation for it yet. That is how our controller looks like until now.
After coding the right List method behavior, shown below, our test pass successfully. Notice that we didn’t write any data access layer code for Product yet. By using the Moq framework, we could fake repository’s behaviour and forget about those boring database scripts and mapping files.
The next step is create the Save operation. Let’s use the same approach, starting with a test case. The test implementation is shown below.
The test above says that when saving a product, the method SaveOrUpdate from IProductRepository is called once and the user is redirected to List action. Again, this test fail because we haven’t implemented that behaviour in ProductController. After writing the code below, our test pass with success.
We are going just fine. However, our tests are starting to present some code duplications. Now, it’s clear that we need to refactor it (Red-Green-Refactor, rememeber?). After some work on it, our test class look like that:
Until now, we tested just the base case. What happens if a user tries to save an invalid model? We have to deal with that in our controller. Let’s write a new test case for it.
This time, we verify that SaveOrUpdate method is never called and the user continues in the same view. Again, the test fail. Here is the new Save implementation that makes the above test pass.
To complete our task of creating a full CRUD for our controller, we still need to implement Delete and Update. However, I will leave it for you as homework
In short, I have shown how to use TDD while creating an ASP.NET MVC application and Moq Framework to isolate presentation layer tests from any other layer of the system.