2011-01-21 39 views
1

在閱讀了關於MVC和測試驅動開發的相當多之後,我剛開始將我的webforms應用程序轉換爲MVC 。我正在使用this書作爲在ASP.NET MVC中學習TDD的參考之一。下面哪個是更好的方式來編寫單元測試,並在ASP.NET MVC中繼續TDD

一股股從本書測試是如下:

[TestMethod()] 
public void Register_Can_Get_To_View() 
{ 
    var target = new AccountController(); 
    var results = target.Register(); 
    Assert.IsNotNull(results); 
    Assert.IsInstanceOfType(results, typeof(ViewResult)); 
    Assert.AreEqual("Register", target.ViewData["Title"]); 
} 

我也有看,從CodePlex上的NerdDinner範例源代碼,並有類似的單元測試如下

[TestMethod] 
public void Index() 
{ 
    // Arrange 
    HomeController controller = new HomeController(); 

    // Act 
    ViewResult result = controller.Index() as ViewResult; 

    // Assert 
    Assert.IsNotNull(result); 
} 
寫入

在第一種情況下,作者正在將結果類型與ViewResult進行比較。然而,在第二種情況下,結果將作爲ViewResult進行處理,並且未經過測試。

哪個更好,我需要如第一種情況那樣詳細測試嗎?

回答

4

理想情況下,您可以測試所有可能出錯的結果,其中null可能只是第一個。

您應該聲明結果的所有值,並且實際上會從不同的角度(即使用不同的輸入)測試它們,以便測試那些結果與輸入相關的正確更改。 (即證明你沒有硬編碼單個測試所需的值,只是爲了讓它通過)。

的想法是:

  1. 編寫一個測試不編譯。
  2. 只夠讓它編譯,但仍然失敗(即NotImplementedException)。
  3. 剛好足夠讓測試通過(您可以硬編碼被測單元以使測試通過)。
  4. 寫另一個失敗的測試(這會強制您將硬編碼放在更好的實現中,以解釋不同的輸入)。
  5. 進行更改,以便測試再次通過。
  6. 重複,直到單元完全測試(即所有可能的/合適的輸入被考慮,並且不合適的輸入被適當地檢查和拒絕)。

有時你可以短路第3步,寫什麼肯特·貝克是指爲明顯實現爲您從經驗中知道事情會很簡單。您不會爲複雜單位執行此操作,但對於一個反轉字符串或將兩個數字相加的方法,您可以繼續並正確編寫實現。

在這種情況下,我會考慮斷言如下:

  • 控制器作用的結果是不爲空。
  • Model屬性的類型正確(假設強類型視圖)。
  • Model中的每個屬性或ViewData中的每個值都是給定輸入的正確值。
+0

測試應該只測試一件事。每個測試你應該使用一個Assert方法。如果您需要檢查多個事物,請考慮編寫更多測試。 – frennky 2011-01-21 13:27:46

1

第一個測試看起來好像控制器操作使用的是ViewData而不是查看模型。對我來說這是糟糕的。它使用魔術弦,它非常脆弱。所以不再需要評論它。

除了驗證控制器操作是否返回視圖之外,第二個測試不會執行任何其他有用的操作。

但是更真實世界的控制器動作會將視圖模型傳遞給此視圖。所以你需要測試這個。我個人更喜歡MVCContrib TestHelper,因爲它讓我的單元測試非常流暢,可讀性:

[TestMethod] 
public void Index() 
{ 
    // Arrange 
    var controller = new HomeController(); 

    // Act 
    var actual = controller.Index(); 

    // Assert 
    actual 
     .AssertViewRendered() 
     .WithViewData<MyViewModel>() 
     .ShouldNotBeNull("the view model was null"); 
} 

在這裏,我們斷言控制器動作呈現的視圖和被傳遞給它的視圖模型是不爲空,這是的預期的類型,因爲相應的視圖將被強制鍵入到該視圖模型中。

相關問題