第一件事的第一......你需要模擬_bookManager
作爲此方法的依賴。
_bookManager
從哪裏來?據推測這是一個班級財產。所以它應該提供一些方法來使用模擬。你應該可能使用構造函數注入,但如果你不熟悉ASP.NET MVC中的依賴關係,那麼它現在可能會過於複雜。注射財產也應該如此。事情是這樣的:
public class MyController
{
private SomeType _bookManager;
public SomeType BookManager
{
get { return _bookManager; }
set { _bookManager = value; }
}
public async Task<ActionResult> Archive()
{
// your method
}
}
想必也是有代碼在類在使用它之前,否則初始化_bookManager
別處。你將要修改該邏輯,以便它不覆蓋任何提供的模擬。一種對我來說經常效果好的模式是使用屬性本身,即使是內部的屬性,也可以在屬性中進行惰性初始化。事情是這樣的:
public class MyController
{
private SomeType _bookManager;
public SomeType BookManager
{
get
{
if (_bookManager == null)
_bookManager = new SomeType();
return _bookManager;
}
set { _bookManager = value; }
}
public async Task<ActionResult> Archive()
{
// IMPORTANT: Use "BookManager" instead of "_bookManager"
}
}
這裏的想法是,如果您爲BookManager
提供一個模擬(或任何依賴實現),那麼代碼將使用它。否則,它會使用你正在使用的任何東西。
既然您的課程設置爲允許使用模擬,您需要創建一個模擬。有許多嘲笑圖書館可用。我個人使用RhinoMocks。
模擬的目的是提供預期的,定義的行爲。這是因爲...
您正在測試Archive()
。您是不測試BookManager.GetArchiveBooks()
使用您選擇的嘲弄庫,在您的測試,你將設立的SomeType
實例(或任何你喜歡的類型叫,很明顯)返回從定義和預期的結果GetArchiveBooks()
。根據這個結果,你可以預測你正在測試的方法的結果並驗證它產生的結果。
從廣義上說,你的測試將是這個樣子:
// arrange
var bookManager = MockRepository.GenerateMock<SomeType>();
// TODO: configure the object to return a known result from GetArchiveBooks()
var controller = new MyController();
controller.BookManager = bookManager;
// act
var result = await controller.Archive();
// assert
// TODO: inspect the result to ensure it contains what you expect
對於您所選擇的嘲弄庫,看看設立了方法的「存根」一些例子被稱爲(在這種情況下爲GetArchiveBooks()
)。
爲了檢查結果,首先你要在調試器中逐步完成這個測試,看看result
實際上有什麼。一個視圖結果有很多屬性,我不知道它們在我頭頂。但是如果你在調試器中檢查它,你應該能夠在其中一個屬性中找到你的模型,以及如果你願意的話你可能會驗證的潛在的其他事情。 (取決於你想在這個測試中聲明多少事情。)
此處的目標是確保返回的模型是,正好是您期望它基於模擬依賴關係的已知行爲。如果是,則該方法通過測試。
編輯:我只注意到在方法的第二依賴性:
HttpContext.User.Identity.GetUserId()
現代ASP.NET MVC的實現可以提供一些有益的方式來嘲笑HttpContext
爲好,雖然我不熟悉我的頭頂。最糟糕的情況是,你只是暴露另一個注射屬性來嘲笑它。事情是這樣的:
private string _userID;
public string UserID
{
get
{
if (string.IsNullOrWhiteSpace(_userID))
_userID = HttpContext.User.Identity.GetUserId();
return _userID;
}
set { _userID = value; }
}
然後在動作方法,你能使用該財產而不是直接調用HttpContext
。在你的測試中,作爲「安排」步驟的一部分,你會提供一個模擬字符串。這是很簡單的:
controller.UserID = "testUser";
正如你可以在這一點看,可測試性所有關於依賴管理。每個單獨的可測試代碼應該與任何和所有的依賴關係隔離,無論它們有多小。 (如從HttpContext
獲取用戶標識。)"Invert" those dependencies允許代碼提供信息,而不是讓您的可測試代碼負責獲取信息。
From [Help](http://stackoverflow.com/help/on-topic):提問作業幫助的問題必須包括您迄今爲止解決問題所做的工作摘要,以及你正在解決它的困難。 –
你當然可以看看像Autofac這樣的IoC,並使用Moq框架來模擬_bookManager類。 –