ASP.NET MVC Tip #3 – Provide Explicit View Names when Unit Testing

In this tip, Stephen Walther explains how you can unit test whether a controller action returns a particular view. He recommends that you be explicit about view names when you plan to create unit tests.

The ASP.NET MVC framework was designed to be a very testable framework. You can easily test an MVC controller action to determine whether the action returns the result that you expect. In this tip, I show you how to test whether a controller action returns a particular view.

Consider the MVC controller, named HomeController, in Listing 1. This controller contains an action named Index(). The Index() action returns a view. However, the name of the view is not provided. Instead, the name of the view is inferred from the name of the controller action. Therefore, when you call the Index() action, a view named Index is returned.

The HomeController contains a second action named Index2(). This second action also returns a view. However, in the second action, the name of the view is explicit. The name of the view is passed to the View() method. This second controller action does the same thing as the first controller action. However, in the case of the first controller action the view name is inferred and in the case of the second controller action the view name is explicit.

Listing 1 - HomeController.vb (VB)

   1: Public Class HomeController
   2:     Inherits System.Web.Mvc.Controller
   3:  
   4:     Function Index() As ActionResult
   5:         Return View() ' view name inferred
   6:     End Function
   7:  
   8:     Function Index2() As ActionResult
   9:         Return View("Index") ' view name explicit
  10:     End Function
  11:  
  12: End Class

Listing 1 - HomeController.cs (C#)

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5: using System.Web.Mvc;
   6:  
   7: namespace Tip3.Controllers
   8: {
   9:     public class HomeController : Controller
  10:     {
  11:         public ActionResult Index()
  12:         {
  13:             return View(); // view name inferred
  14:         }
  15:  
  16:         public ActionResult Index2()
  17:         {
  18:             return View("Index"); // view name explicit
  19:         }
  20:  
  21:     
  22:     }
  23: }

If you plan to create unit tests for your ASP.NET MVC application, then you should always be explicit about your view names. Otherwise, you won’t be able to test whether the right view was returned in your unit tests.

The test class in Listing 2 contains two test methods. The first method tests the HomeController’s Index() action and the second method tests the HomeController’s Index2() action. The first test always fails and the second test always succeeds (see Figure 1).

Listing 2 - HomeControllerTest.vb (VB)

   1: Imports System
   2: Imports System.Collections.Generic
   3: Imports System.Text
   4: Imports System.Web.Mvc
   5: Imports Microsoft.VisualStudio.TestTools.UnitTesting
   6: Imports Tip3
   7:  
   8: <TestClass()> Public Class HomeControllerTest
   9:  
  10:  
  11:     <TestMethod()> _
  12:   Public Sub Index()
  13:         ' Arrange
  14:         Dim controller As New HomeController()
  15:  
  16:         ' Act
  17:         Dim result As ViewResult = controller.Index()
  18:  
  19:         ' Assert
  20:         Assert.AreEqual("Index", result.ViewName)
  21:     End Sub
  22:  
  23:     <TestMethod()> _
  24:   Public Sub Index2()
  25:         ' Arrange
  26:         Dim controller As New HomeController()
  27:  
  28:         ' Act
  29:         Dim result As ViewResult = controller.Index2()
  30:  
  31:         ' Assert
  32:         Assert.AreEqual("Index", result.ViewName)
  33:     End Sub
  34:  
  35:  
  36:  
  37: End Class

Listing 2 - HomeControllerTest.cs (C#)

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using System.Web.Mvc;
   6: using Microsoft.VisualStudio.TestTools.UnitTesting;
   7: using Tip3;
   8: using Tip3.Controllers;
   9:  
  10: namespace Tip3Tests.Controllers
  11: {
  12:     /// <summary>
  13:     /// Summary description for HomeControllerTest
  14:     /// </summary>
  15:     [TestClass]
  16:     public class HomeControllerTest
  17:     {
  18:         [TestMethod]
  19:         public void Index()
  20:         {
  21:             // Arrange
  22:             HomeController controller = new HomeController();
  23:  
  24:             // Act
  25:             ViewResult result = controller.Index() as ViewResult;
  26:  
  27:             // Assert
  28:             Assert.AreEqual("Index", result.ViewName);
  29:         }
  30:  
  31:  
  32:         [TestMethod]
  33:         public void Index2()
  34:         {
  35:             // Arrange
  36:             HomeController controller = new HomeController();
  37:  
  38:             // Act
  39:             ViewResult result = controller.Index2() as ViewResult;
  40:  
  41:             // Assert
  42:             Assert.AreEqual("Index", result.ViewName);
  43:         }
  44:  
  45:  
  46:     }
  47: }

Figure 1 – Unit Test Results

image

A unit test cannot infer a view name. My recommendation is that you should always be explicit about your view names if you plan to unit test your application.

Download the Code

2 Comments

Comments have been disabled for this content.