The ASP.NET MVC and Web API project templates include the option to create a unit test project associated with your web project. When you create a new web project (File, New Project), Visual Studio launches the unified web application creation dialog, as shown in Figure 8.10. Notice the Add Unit Tests option in the lower left. Checking this box for the MVC and Web API templates ensures that a companion unit test project is created with all the proper references (including a reference to your web application).
Notice in Figure 8.10 that we are starting with an empty web project configured for Web API. We are also creating a test project for testing the controller classes we create for the Web API application. As an example, imagine our Web API exposes methods for accessing an invoice object similar to what was discussed earlier in this chapter. Let’s take a look at the Web API code and the unit test.
Note
This section assumes you are familiar with ASP.NET MVC/Web API. If not, please check Chapters 17, “Building Modern Websites with ASP.NET 5” and 19, “Building and Consuming Services with Web API and WCF.”
Before writing the unit test, we must have something to test. In this example, we get started by adding a model to the Web API project. You can do so by navigating to the project in Solution Explorer and right-clicking the Models
folder. Here we choose Add, New Item. From the New Item dialog, we select a class and name it Invoice
. We then write code to represent the invoice object and invoice line items as shown in Figure 8.11. (You can get this code as a sample from the book download.)
The next step is to write a controller for serving up HTTP web services around the invoice model. The public members of this controller will be exposed as services for HTTP clients such as browsers, mobile devices, and desktop applications.
To get started, inside Solution Explorer, right-click the Controllers folder and choose Add, Controller. This will launch the Add Scaffold dialog; from here, we choose the Web API empty controller. This will create a simple controller class that inherits from System.Web.Http.ApiController
.
We now need to add HTTP services for accessing the invoice. In this example, we will create two services: GetInvoice
and GetInvoiceLineItems
. Both services use an internal method to simulate (with a switch
statement) looking up these domain items from a database. Figure 8.12 shows the two services and the stubs for the private lookup methods. These are typical, albeit simple, web services you would create using Web API. (Again, see Chapter 19 for details.)
Before we can create a unit test for the Web API controller, we must install and reference key components of the Web API. Visual Studio did not automatically do these tasks for us in the version of the project we created (Empty, Web API + unit tests). We can accomplish this task through NuGet.
Right-click Reference under the unit test project inside Solution Explorer and choose Manage NuGet Packages. This will launch the NuGet Package Manager as shown in Figure 8.13. Here we search for the Web API package by typing asp.net web api
into the search box (upper-right of Figure 8.13). Next, select Microsoft.AspNet.WebApi.Core
and choose Install.
We can verify the installation by confirming the new references were added to the project. Notice that most of these reference match those in the Web API project. This ensures you can create a client that accesses the same types the controller uses. We use NuGet (versus setting Framework references) to get a matching version of the Web API libraries installed in the test project. For instance, if you right-click a reference and look at the Properties dialog, you will notice that version numbers match between the two projects.
The test method can now be written. In this example, we first rename the test class to WebApiInvoiceTest
. Next, we add a using
statement to the top of the class for System.Web.Http.Results
. This allows us to use the OkNegotiatedContentResult
class when calling GetInvoice
. It also allows us to strongly type the results to the Invoice
class from the model. We access these results through the object’s Content
property (as shown in the final assertion in Listing 8.3).
using System;
using System.Web.Http;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Http.Results;
namespace TestWebApi.Tests
{
[TestClass]
public class WebApiInvoiceTest
{
[TestMethod]
public void VerifyInvoiceTotal()
{
int invoiceId = 1500;
//create controller instance for testing
var controller = new Controllers.InvoiceController();
//get an invoice
var invoice = controller.GetInvoice(invoiceId) as
OkNegotiatedContentResult<Models.Invoice>;
//get the invoice line items
var lineItems = controller.GetInvoiceLineItems(invoiceId);
//verify the invoice total matches the total of line items
double verifyTotal = 0;
foreach (var item in lineItems)
{
verifyTotal += item.Price * item.Quantity;
}
//assert results of test
Assert.AreEqual(invoice.Content.Total, verifyTotal);
}
}
}
Notice that the TestMethod
works the same as the other unit test methods we wrote earlier in the chapter. The big wrinkles here are using the Web API core for creating the client to access the controller and the objects inside System.Web.Htttp.Results
for dealing with HTTP results from the service. Figure 8.14 shows the results of the test running inside Visual Studio.