繁体   English   中英

设置模拟ViewModel以进行单元测试

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM