![](/img/trans.png)
[英]Injected mocked dependency into ViewModel while unit testing not behaving as expected
[英]Setup Mocked ViewModel for Unit Testing
這是場景:
我正在為控制器編寫測試,並且需要設置一個名為CheckoutViewModel
的視圖模型。 我的控制器方法Products
不將CheckoutViewModel
作為參數,因此無法以這種方式傳遞它。
當前,由於未設置和調用CheckoutViewModel
,因此測試無法返回Null Exception
。
問題:如何使用數據設置
CheckoutViewModel
。
錯誤詳情:
System.NullReferenceException
你調用的對象是空的
當前測試
[TestMethod]
public void Products_ProductControllerIsCalled_ReturnsViewWithProducts()
{
// Arrange
var currentSession = _autoMoqer.GetMock<ICurrentSession>().Object;
ProductController productController = new ProductController(currentSession);
var checkoutViewModel = new CheckoutViewModel
{
CheckoutId = new Guid()
};
// Act
ActionResult result = productController.Products();
// Assert
Assert.IsInstanceOfType(result, typeof(ViewResult));
}
控制者
[AccectReadVerbs]
public ActionResult Products()
{
CheckoutViewModel checkoutViewModel = GetCheckoutViewModel();
var checkoutId = checkoutViewModel.CheckoutId;
var result = _productOrchestrator.Products(checkoutId, currentSession)
return View(result);
}
無法使用此方法
private CheckoutViewModel GetCheckoutViewModel()
{
if(Session["CheckoutViewModel"] == null)
{
return new CheckoutViewModel();
}
return (CheckoutViewModel)Session["CheckoutViewModel"];
}
如果GetCheckoutViewModel對服務,dbConnection或其他復雜類具有某些依賴關系,則需要添加具有接口的類,將GetCheckOutViewModel的方法移至該類,然后將新接口作為對控制器的依賴關系。 然后,您需要模擬新界面。
或編輯您的視圖模型以獲取依賴於單元測試(即會話)的接口的接口依賴性。
我認為您可以創建一些接口:
public interface ISessionManager { Session session {get; set;} }
然后是您的控制器構造函數:
public ProductsController(ISessionManager sm) { _sessionManager = sm; }
然后,您可以將模擬實例傳遞給控制器。
我猜這是由於以下事實造成的:當您運行單元測試時,將沒有任何可用的(網絡服務器) 會話 。 您要做的就是將測試與任何外部依賴關系隔離開-並且作為Web服務器托管環境一部分的會話狀態將是一個外部依賴關系。
為了解決這個問題,您需要從測試中模擬或存根Session對象。 有許多方法可以做到這一點,但最簡單的方法是將Session設為Controller上的公共屬性。 然后從測試中將會話設置為在測試中創建的實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.