單元測試學習筆記03_Mock Framework介紹(Moq)_MVC專案的UnitTest介紹
在上一篇中介紹到有分所謂Stub跟Mock的做法
那在一般實作中較常用到的是模擬物件 Mock,因為很常我們處裡道的是
沒有回傳值的情況,因此比較著重在互動方式的驗證。
這類模擬物件的技法可以幫助我們在開發階段中不會
因為正式環境還沒準備好就無法驗證程式的窘境
但若要每次都自己寫Mock其實也滿費時的
因此就有推出許多Mock框架
在此先介紹Moq
也可輕鬆定義模擬物件包含visual studio intellisense整合使減輕測試的麻煩
此外Moq強型別的特性也能降低測試程式撰寫發生錯誤機率
新建一個MVC包含UnitTest的專案
在此順帶觀察MVC專案的UnitTest寫作方式
預設產生的示例
我們這裡已經事先準備寫好的一個BeginController 類別
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MVC_UniTestApp.Controllers { public class BeginController : Controller { // GET: Begin public ActionResult Show() { ViewBag.Message = "早安你好"; return View(); } } } |
而我們在測試專案中的Controller目錄可再增加測試類與相關測試method
BeginControllerTest 類別
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using MVC_UniTestApp.Controllers; using System.Web.Mvc; namespace MVC_UniTestApp.Tests.Controllers { [TestClass] public class BeginControllerTest { [TestMethod] public void ShowTest() { var ctrl = new BeginController(); var result = ctrl.Show() as ViewResult; Assert.AreEqual("早安你好",result.ViewBag.Message); } } } |
執行後即可有相對測試結果產出
Moq下載方式
可透過指令
Install-Package Moq
這邊對BeginController擴充一個回傳尚未實作例外的Action
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MVC_UniTestApp.Controllers { public class BeginController : Controller { // GET: Begin public ActionResult Show() { ViewBag.Message = "早安你好"; return View(); } //情境1.比方同事A要負責寫一個資料陳列的功能,同事B才能接續開發和進行驗證,但此時不想等,就可先叫同事A寫一個空殼的概念 //情境2.比方還正在跟User洽談了解規格在開發過程只是先模糊知道有一個資料陳列的功能 public virtual ActionResult List() { throw new NotImplementedException(); } } } |
在搭配Moq開發時候
必須用virtual來修飾使其可被覆寫
導入Mock的單元測試撰寫
ListTest()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using MVC_UniTestApp.Controllers; using System.Web.Mvc; using Moq; namespace MVC_UniTestApp.Tests.Controllers { [TestClass] public class BeginControllerTest { [TestMethod] public void ShowTest() { var ctrl = new BeginController(); var result = ctrl.Show() as ViewResult; Assert.AreEqual("早安你好", result.ViewBag.Message); } [TestMethod] public void ListTest() { var mock = new Mock<BeginController>(); mock.Setup(c => c.List()).Returns(new ViewResult() { ViewName = "List" }); var ctrl = mock.Object; var result = ctrl.List() as ViewResult; Assert.AreEqual("List",result.ViewName); } } } |
Moq框架主要核心也就是Mock Class型別
在其建構子中去透過指定特定物件型別來產生實體模擬出相應行為
在Mock中提供兩個方法
一個Setup
public ISetup<T> Setup(Expression<Action<T>> expression);
Specifies a setup on the mocked type for a call to a non-void (value-returning)
設定(Setup)目標要模擬的特定物件
一個Returns
IReturnsResult<TMock> Returns(TResult value);
Specifies the value to return.
預期回傳模擬的行為結果
public virtual T Object { get; }
Exposes the mocked object instance.
要取出模擬物件則透過.Object屬性來存取
這邊測試是可以過得
預設ViewName就是Action方法名稱
留言
張貼留言