2011-04-13 72 views
1

我對單元測試相當陌生,無法繞過如何測試(或者如果我甚至應該)這種情況。mspec&rhino mocks預計的異常測試

我有一個控制器的方法(僞碼):

public ActionResult Register(formModel model) 
{ 

    if (ModelState.isValid) { 

     try { 

      _userService.CreateUser(a bunch of parameters here); 
      return RedirectToAction(some other action); 
     } 
     catch (Exception e) 
     { 

      ModelState.AddModelError("",e.Message); 

     } 

    } 

    return View(); 
} 

我有一堆的反對 「_userService」 單獨的測試。 「CreateUser」方法只是創建一個新用戶並且不返回任何內容,或者如果出現錯誤(例如,用戶存在),我會在控制檯環繞一個try catch並將該異常添加到ModelState中時引發異常。

從我的理解我應該嘲笑的服務,並斷言它被正確調用(我使用assertwascalled語法),因爲它什麼都沒有返回,我只是想知道我的控制器調用它。

我不確定如何測試,當用戶服務拋出一個錯誤時,它不應該重定向,應該將該異常添加到模型狀態。隨着犀牛嘲笑,你可以嘲笑一個模擬,但單元測試的書籍藝術建議反對。

現在在我的測試中,我手動添加一個模型錯誤(不關心它是否來自用戶服務)並測試控制器是否返回相同視圖(如果有錯誤)。這是否是正確的方法呢?或者我應該創建一個單獨的測試,在其中存儲_userService以引發錯誤並檢查它是否添加到模型狀態?或者我應該甚至不測試這種情況?我覺得我可能只是在分析整個事情,並使用模型狀態測試將足以滿足此...

回答

1

你的模擬代表一個合作的類。我不會太嘲笑模擬和存根之間的區別;它仍然是一個合作班。

您可以將單元測試視爲描述如何使用您的課程以及課程與合作者的交互方式。你有兩個例子:

Given a controller 
When I register the model 
Then the class should ask the user service to create a user. 

和:

Given a controller 
Given the user service is broken 
When I register the model 
Then the class should attach the error to the model state. 

這是第二Given,告訴你,你磕碰而不是嘲笑。您正在將用戶服務設置爲已損壞。類行爲的上下文是不同的,所以你需要存根,你應該確實拋出一個異常。

如果您將這些行作爲註釋放入您的測試中,它就會有意義。如果有道理,可以忽略這本書。

順便說一下,這是單元級BDD。您可以在單元級別使用「給定,當時,然後」,就像在場景級別一樣,它可以幫助您考慮測試的邏輯。不要爲此使用BDD場景工具。

+0

謝謝!這對我來說是有意義的,以此來測試它。 – maciek 2011-04-14 13:50:13