[英]Unit test to check if an action method called the service layer
我有一個名為NewsController的控制器,該控制器的構造函數接收一個INewsService作為參數。
我在此控制器中有一個名為GetAllNews()的方法,該方法返回用於填充YUI數據表的JSON結果。 我想編寫一個單元測試,以檢查是否調用了新聞服務的FindAll方法以返回所有新聞項。 我該怎么做? 我目前擁有的是:
public JsonResult GetAllNews()
{
var items = newsService.FindAll();
var jsonResult = Json(items);
return jsonResult;
}
我對控制器的單元測試如下:
public NewsControllerTest()
{
newsServiceStub = MockRepository.GenerateStub<INewsService>();
newsController = new NewsController(newsServiceStub);
}
[Test]
public void GetAllNews_should_use_news_service()
{
// Arrange
List<News> newsList = new List<News>();
newsServiceStub.Stub(s => s.FindAll()).Return(newsList);
// Act
var actual = newsController.GetAllNews();
// Assert
newsServiceStub.VerifyAllExpectations();
}
測試通過上面的代碼。 但是,如果我將GetAllNews()更改為如下所示,那么它也會通過。 它不應該失敗嗎? 我要測試的是GetAllNews()是否使用新聞服務:
public JsonResult GetAllNews()
{
return null;
}
如果您可以擺脫它,請不要單元測試是否調用了特定方法。 單元測試的重點是測試行為,而不是實現。 測試調用FindAll
就是測試實現。 這將導致脆弱的測試,如果您更改實現但行為不會改變,該測試會中斷。 客戶不在乎如何獲取所有新聞,他們只是希望您獲取所有新聞。
所以
public void GetAllNews_should_use_news_service()
應該
public void GetAllNews_should_get_all_the_news
我將把編碼細節留給您。
正如其他人指出的那樣,從長遠來看,對特定方法調用的測試可能很脆弱。
但是,從Rhino.Mocks的角度來看,如果要檢查期望,則應該使用Mock而不是Stub。 將您的GenerateStub
更改為GenerateMock
然后將.Stub()
調用更改為.Expect()
調用。 那應該修復您的測試。
您可能會發現Martin Fowler的這篇文章對模擬和存根之間的區別很感興趣。
http://www.martinfowler.com/articles/mocksArentStubs.html
Fowler指出,存根用於狀態驗證,而模擬用於行為驗證 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.