為ASP.NET MVC應用程式建立單元測試

來源:互聯網
上載者:User

本教程的目的是解釋如何為 ASP.NET MVC 應用程式中的控制器編寫單元測試。我們將討論如何建立三種不同類型的單元測試。您將瞭解如何測試控制器操作返回的視圖、如何測試控制器操作返回的視圖資料,以及如何測試一個控制器操作是否重新導向到另一個控制器操作。

建立測試控制器

我們首先建立要測試的控制器。程式清單 1 中包含名稱為 ProductController 的控制器。

程式清單 1 ProductController.cs

 

using System;
using System.Web.Mvc;

namespace Store.Controllers
{
    public class ProductController : Controller
    {
          public ActionResult Index()
          {
              // Add action logic here
              throw new NotImplementedException();
          }

          public ActionResult Details(int Id)
          {
              return View("Details");
          }
    }
}

 

HomeController 包含兩個操作方法,名稱為 Index() 和 Details()。兩個操作方法都返回一個視圖。請注意, Details() 操作接受名稱為 Id 的參數。

 

測試控制器返回的視圖

假設要測試 ProductController 是否返回正確的視圖。希望確保當啟用 ProductController.Details() 操作時,返回 Details 視圖。程式清單 2 中的測試類別包含一個單元測試,用於測試由 ProductController.Details() 操作返回的視圖。

程式清單 2 ProductControllerTest.cs

 

using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Store.Controllers;

namespace StoreTests.Controllers
{
    [TestClass]
    public class ProductControllerTest
    {
          [TestMethod]
          public void TestDetailsView()
          {
              var controller = new ProductController();
              var result = controller.Details(2) as ViewResult;
              Assert.AreEqual("Details", result.ViewName);
          }
    }
}

 

程式清單 2 中的類包含名稱為 TestDetailsView() 的測試方法。此方法包括三行代碼。第一行代碼建立一個 ProductController 類的新執行個體。第二行代碼啟用控制器的 Details() 操作方法。最後一行代碼檢查 Details() 操作返回的是否是 Details 視圖。

ViewResult.ViewName 屬性代表由控制器返回的視圖的名稱。測試該屬性時需要特別小心。控制器返回視圖有兩種方法。控制器可以顯式地返回視圖,如下所示:

 

public ActionResult Details(int Id)
{
    return View("Details");
}

 

另外,視圖的名稱可以引用控制器操作的名稱,如下所示:

 

public ActionResult Details(int Id)
{
    return View();
}

 

此控制器操作也返回名稱為 Details 的視圖。然而,視圖的名稱引用自操作的名稱。如果想要測試檢視名稱,則必須顯式地從控制器操作返回視圖名稱。

通過按 Ctrl-R,A 按鍵組合或單擊 Run All Tests in Solution 按鈕( 1 所示),可以運行程式清單 2 中的單元測試。如果通過測試,則將看到 2 所示的 Test Results 視窗。

圖 1:運行解決方案中的所有測試

圖 2:成功!

測試控制器返回的 View Data

MVC 控制器使用 View Data 將資料傳遞給視圖。例如,假設想要在啟用 ProductController Details() 操作時顯示某個產品的詳細資料。在這種情況下,可以建立 Product 類的執行個體(在模型中定義),然後利用 View Data 將執行個體傳遞給 Details 視圖。

程式清單 3 中修改後的 ProductController 包含更新的 Details() 操作,它返回 Product。

程式清單 3 ProductController.cs

 

using System;using System.Web.Mvc;namespace Store.Controllers{     public class ProductController : Controller     {          public ActionResult Index()          {               // Add action logic here               throw new NotImplementedException();          }          public ActionResult Details(int Id)          {               var product = new Product(Id, "Laptop");               return View("Details", product);          }     }}

 

首先,Details() 操作建立 Product 類的新執行個體表示膝上型電腦。接下來,Product 類的執行個體被作為第二個參數傳遞給 View() 方法。

可以編寫測試單元測試預期的資料是否包含在視圖資料中。程式清單 4 中的單元測試用於測試表示膝上型電腦的 Product 是否在調用 ProductController Details() 操作方法時返回。

程式清單 4 ProductControllerTest.cs

 

using System.Web.Mvc;using Microsoft.VisualStudio.TestTools.UnitTesting;using Store.Controllers;namespace StoreTests.Controllers{     [TestClass]     public class ProductControllerTest     {          [TestMethod]          public void TestDetailsViewData()          {               var controller = new ProductController();               var result = controller.Details(2) as ViewResult;               var product = (Product) result.ViewData.Model;               Assert.AreEqual("Laptop", product.Name);          }     }}

 

在程式清單 4 中,TestDetailsView() 方法通過啟用 Details() 方法測試返回的 View Data。ViewData 公開為 ViewResult(通過啟用 Details() 方法返回)上的一個屬性。ViewData.Model 屬性包含傳遞給視圖的產品。測試只是簡單地驗證封裝含在 View Data 中的產品名稱是 Laptop。

 

測試控制器返回的操作結果

較複雜的控制器操作可能返回不同類型的操作結果,具體取決於傳遞給控制器操作的參數值。控制器操作可以返回各種類型的操作結果,包括 ViewResult、RedirectToRouteResult 或 JsonResult。

例如,程式清單 5 中修改的 Details() 操作在將有效 Id 傳遞給操作時返回 Details 視圖。如果傳遞無效的產品 Id(Id 的值小於 1),則將重新導向到 Index() 操作。

 

程式清單 5 ProductController.cs

 

using System;using System.Web.Mvc;namespace Store.Controllers{     public class ProductController : Controller     {          public ActionResult Index()          {               // Add action logic here               throw new NotImplementedException();          }          public ActionResult Details(int Id)          {               if (Id < 1)                    return RedirectToAction("Index");               var product = new Product(Id, "Laptop");               return View("Details", product);          }     }}

 

可以使用程式清單 6 中的單元測試來測試 Details() 操作的行為。程式清單 6 中的單元測試驗證當 Id 值 -1 被傳遞到 Details() 方法時是否重新導向到 Index 視圖。

 

程式清單 6 ProductControllerTest.cs

 

using System.Web.Mvc;using Microsoft.VisualStudio.TestTools.UnitTesting;using Store.Controllers;namespace StoreTests.Controllers{     [TestClass]     public class ProductControllerTest     {          [TestMethod]          public void TestDetailsRedirect()          {               var controller = new ProductController();               var result = (RedirectToRouteResult) controller.Details(-1);               Assert.AreEqual("Index", result.Values["action"]);          }     }}

 

在調用控制器操作的 RedirectToAction() 方法時,控制器操作返回 RedirectToRouteResult。測試用於檢查 RedirectToRouteResult 是否將使用者重新導向到名稱為 Index 的控制器操作。

 

總結

 

在本教程中,我們學習了如何為 MVC 控制器操作構建單元測試。首先,我們學習了如何驗證控制器操作是否返回正確的視圖。學習了如何使用 ViewResult.ViewName 屬性驗證視圖的名稱。

接下來,我們研究了如何測試 View Data 的內容。學習了如何檢查調用控制器操作後 View Data 中是否返回正確的產品。

最後,我們討論了如何測試控制器操作是否返回不同類型的操作結果。學習了如何測試控制器操作是返回 ViewResult 還是 RedirectToRouteResult。

 

轉自:http://www.uml.org.cn/Test/200912248.asp

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.