![](/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.