繁体   English   中英

在两种情况下,ViewData.Model的行为有所不同.. MVC4应用程序中的UnitTesting失败

[英]ViewData.Model is behaving differently in two cases .. UnitTesting failed in MVC4 application

我有以下两种测试方法,它们正在测试相同的动作方法。 第一个失败,第二个失败。 这是一个Asp.net mvc4应用程序...请对此提供帮助...

//Action method     
public ViewResult Edit(int productID)
{
    Product product = 
    productRepository.Products.FirstOrDefault(p => p.ProductID == productID);           
    return View(product);
}
[TestMethod]
public void Can_Edit_Product() //Failed, result2 is set with product - "P1"
{ 
    //Arrange
    Mock<IProductRepository> mock = new Mock<IProductRepository>();
    mock.Setup(p => p.Products).Returns(new Product[] {
            new Product{ ProductID=1, Name="P1" },
            new Product{ ProductID=2, Name="P2"}
    }.AsQueryable());
    AdminController target = new AdminController(mock.Object);                

    //Act
    Product result1 = target.Edit(1).ViewData.Model as Product;
    Product result2 = target.Edit(3).ViewData.Model as Product;

    //Assert
    Assert.AreEqual("P1", result1.Name);
    Assert.IsNull(result2);
}

[TestMethod]
public void Cannot_Edit_Nonexistant_Product() //Passed
{
    //Arrange
    Mock<IProductRepository> mock = new Mock<IProductRepository>();
    mock.Setup(p => p.Products).Returns(new Product[] {

           new Product{ ProductID=1, Name="P1" },
           new Product{ ProductID=2, Name="P2"}
    }.AsQueryable());
    AdminController target = new AdminController(mock.Object);

    //Act            
    Product result2 = target.Edit(3).ViewData.Model as Product;

    //Assert
    Assert.IsNull(result2);            
}

对于失败的测试,我发现该操作方法正确返回了null,但是不知何故Model对象未设置为null,而是将其设置为第一个产品。 这真的很神秘...这里发生了什么...

[在上面的代码productRepository.Products类型为IQueryable ...,并且我使用Moq进行模拟]

我将第一次测试分开了,但看起来您已经知道了,您只是在要求解释。 根据您的描述,控制器ViewData.Model首次正确设置。 因此target.ViewData.Model是正确的。 当您第二次设置它时,也许ViewData.Model根本不会被覆盖(框架可能会假设,如果您向视图提供null ,则默认情况下它会为null而会忘记它)。 请记住,在Web应用程序的上下文中,这些操作将被调用一次,然后所有视图数据将被丢弃,直到下一个请求。 因此,下一个请求ViewData.Model将再次以null开头。 因此,每个测试方法只能进行一个控制器动作测试。

我没有检查源代码,但这似乎是对我的可能解释。 您可以通过执行以下操作来检查我在解释什么。

AdminController target = new AdminController(mock.Object);                

Product result1 = target.Edit(1).ViewData.Model as Product; // ViewData.Model will be product 1 
Product result2 = target.Edit(3).ViewData.Model as Product; // ViewData.Model is still product 1
Product result2 = target.Edit(2).ViewData.Model as Product; // ViewData.Model will be product 2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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