2009-11-24 53 views
20

我已經閱讀了很多關於測試驅動開發(TDD)的內容,我發現基於個人經驗的原理非常引人注目。ASP.NET MVC的測試驅動開發 - 從哪裏開始?

目前我正在爲我參與的初創項目開發一個網站,並且我想嘗試將TDD付諸實踐。

所以...我在Visual Studio 2010中創建一個空白的解決方案,添加一個ASP.NET MVC Website項目和一個測試項目。

我還爲我的域對象和一個測試項目添加了一個名爲「Domain」的類庫。

現在我想知道從哪裏開始。在做任何事情之前,我應該寫一個測試嗎?問題是 - 我應該開始編寫域對象的測試嗎?如果是這樣,我應該測試什麼,因爲域對象還不存在?

或者我應該從網站項目開始並編寫測試嗎?如果是這樣,我應該寫什麼測試?主控制器/索引操作?

回答

11

我通常首先收集一系列我將要開發的應用程序的故事。從那我產生一個領域模型,通常在「紙」上。我組織了將要實施的故事,並開始在數據庫中爲第一組故事創建領域模型。

一旦我有了初始數據庫,那麼我使用ORM(在我的例子中爲LINQ to SQL)將數據庫表映射到一組初始類。我通常不會單元測試生成的代碼,所以這給了我相當數量的代碼作爲開始的基礎。然後我創建一個存根方法,它引發一個未實現的異常,以實現我正在使用的第一個域類的一個特徵。通常,我從驗證邏輯開始。一旦你有了存根方法,那麼你可以使用VS右鍵菜單爲該方法創建一個或多個單元測試。然後,你在路上。

一旦我完成了第一個故事的域對象,我就開始使用MVC方面。首先,我將爲第一個視圖創建視圖模型。就這一點而言,這些通常只是一個空容器類。然後,我將創建視圖並將其強制輸入到視圖模型。我將開始充實視圖,根據視圖的需要向視圖模型添加屬性。請注意,由於視圖模型只是一個容器,通常不會有與其關聯的單元測試。然而,它將在隨後的控制器測試中使用。

一旦視圖完成(或者至少我的初始概念已完成),然後我爲它創建存根控制器操作或操作,再次,存根方法只是拋出未實現的異常。這足以讓它編譯並讓我使用這些工具爲它創建單元測試。我會根據需要繼續測試方法並確保它對給定輸入適當地執行操作並生成適當的視圖模型。如果該方法可以產生多個視圖模型,即渲染多個視圖,則我可以迭代創建視圖模型/視圖/控制器代碼的過程,直到故事或故事完成。

根據需要重複,直到您的故事集實施,重構一路上。

3

編寫單元測試,甚至宣佈要測試的類似乎在靜態語言,如C#有點極端了。所以你首先聲明你的域類,然後拋出一些接口來定義你將在這些域對象上執行的操作,然後添加一個將實現接口的類,只留下方法NotImplementedException。那時你可以爲這個類編寫單元測試,因爲所有類型都是已知的。你運行測試失敗,然後你執行該方法並再次運行測試 - 它會通過。然後你可以重構和優化你的實現,你的單元測試仍然應該通過。

一旦你有一個很好的領域模型和數據訪問層,你可以移動到你創建控制器的web項目,使用你之前定義的接口(通過構造一個接口)。您通過用模擬對象替換接口來爲此控制器編寫單元測試,以便您可以獨立於數據訪問代碼測試控制器操作。

最重要的是:不要害怕添加類和接口。我曾見過人們寫出巨大的方法來同時執行多種事情,而且很難測試。嘗試將不同的任務分離到您可以輕鬆編寫規範的方法中:對於不同的可能輸入,您希望得到什麼輸出。

2

對於很長的答案,你應該採取這樣的小步驟。

1) - 第一寫一個失敗的測試

[Test] 
    public void AddSameTag() 
    { 
     UserMovie userMovie = new UserMovie(); 

     userMovie.AddTag("action", "dts", "dts"); 
     Assert.AreEqual(2, userMovie.Tags.Count); 
    } 

2) - 寫通過測試簡單的代碼。

public virtual void AddTag(params string[] tags) 
    { 
     foreach (var text in tags) 
     { 
      Tag tag =new Tag(text.Trim()); 
      if (!movieTags.Contains(tag)) 
       movieTags.Add(tag); 
     } 
    } 

3) - 重構

。 對於ASP.NET MVC和TDD初學者,您可以忽略控制器測試,並關注TDD的域。