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

來源:互聯網
上載者:User

這篇文章主要示範如何為ASP.NET MVC應用程式建立單元測試。這裡我們討論了如何建三類單元測試
測試控制器返回特定的視圖
測試控制器返回特定的View Data
測試控帽器返回特定的Action Result

一、建立要測試的控制器
我們把要測試的控制器命名為ProductController,代碼如下:
Listing 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");          
   }     
}
}
ProductController控制器包含兩個控制動作Index()和Details()。兩個控制器都返回視圖,另外Details()動作接收一個名子為Id的形參

二、測試控制器返回的視圖。(原創:灰灰蟲的家 http://hi.baidu.com/grayworm)
假設我們要測試ProductController是否返回正確的視圖,確保ProductController.Details()動被能夠被調用,並返回Details視圖。下面的程式碼封裝含了測試ProductController.Details()動作的單元測試
Listing 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);
          
   }     
}
}
在上面的代碼中我們定義了一個TestDetailsView()方法,這個方法包含了三行代碼,第一行代碼是建立ProductController類的執行個體。第二行代碼調用控制器的Details()動作方法。最後一行代碼檢查Details()動作是否返回Details視圖。
ViewResult.ViewName屬性工作表示由控制層返回視圖的名稱。控制器有兩種返回視圖的方法:
1.控制器動作以顯式地返回視圖名稱
public ActionResult Details(int Id) {      return View("Details"); }

2.控制器動作返回視圖的預設名稱是控制器動作名
public ActionResult Details(int Id) {      return View(); }

但如果我們要測試返回視圖的名稱,那我們必須在控制器動作中顯式返回視圖名稱。

我們可以按Ctrl+R,A來運行單元測試,也可以點擊Run All Tests in Solution按鈕,如所示,如果單元測試運行通過,我們會在Test Results視窗中看到測試結果,如所示

《圖1》

《圖2》

三、測試控制器返回的ViewData(原創:灰灰蟲的家 http://hi.baidu.com/grayworm)
MVC控制器通過ViewData向視圖層返回資料。例如,假設我們想在調用ProductController.Details()動作後,顯示特定產品的詳細資料。那我們可以在Details()動作中建立Product執行個體,並使用ViewData把它傳遞給Details視圖
Details()動作代碼如下所示,返回一條產品資訊。
Listing 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的執行個體,該執行個體是一台laptop電腦,然後我們把它傳入View()方法中。
我們可以編寫單元測試,以檢查在Details()返回的ViewData資料中是否包含預期的資料。下面的代碼是來測試ProductController.Details()動作是否返回一個laptop電腦的產品執行個體。
Listing 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);          
   }     
}
}
在上面的代碼中,TestDetailsView()方法用來測試Details()控制動作返回的ViewData。該ViewData是Details()動作以ViewResult的屬性形式出現的。ViewDataModel包含傳遞給視圖的產品。該測試就是檢查控制器動作返回的ViewData中產品的名子是否是LapTop。

四、測試控制器返回的Action Result(原創:灰灰蟲的家 http://hi.baidu.com/grayworm)
複雜的控制器動作往往根據傳入的參數不同而返回不同類型的Action Result。控制器動作可以返回各種Action Result。如ViewResult、RedirectToRouteResult和JsonResult。
例如下面的代碼,Details動作接收一個Id參數,當我們傳遞合法的Id(Id>=1)進去的時候,Details()動作返回Details視圖,如果傳遞的Id不合法(Id<1)時,Details()動作跳轉到Index()動作。
Listing 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);
          
   }     
}
}

我們可以編寫下面的測試代碼來測試Details()動作的行為。下面的測試代碼主要來檢驗當我們傳遞-1給Details()動作時,能否跳轉到Index視圖。
Listing 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屬笥來驗證返回的視圖名稱
然後,我們學習如何檢驗返回的ViewData的內容。這裡我們檢驗控制器動作是否在ViewData中返回正確的產品資訊。
最後,我們討論了如何測試控制器是否返回多個ActionResult。這裡我們測試了控制器返回的是ViewResult還是RedirectToRouteResult。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.