Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ViewData.Model在两种情况下表现不同。。MVC4应用程序中的单元测试失败_C#_Unit Testing_Asp.net Mvc 4 - Fatal编程技术网

C# ViewData.Model在两种情况下表现不同。。MVC4应用程序中的单元测试失败

C# ViewData.Model在两种情况下表现不同。。MVC4应用程序中的单元测试失败,c#,unit-testing,asp.net-mvc-4,C#,Unit Testing,Asp.net Mvc 4,我有以下两种测试方法,它们测试相同的动作方法。第一个失败,第二个通过。这是一个Asp.net mvc4应用程序。。。请帮我做这个 //Action method public ViewResult Edit(int productID) { Product product = productRepository.Products.FirstOrDefault(p => p.ProductID == productID); retur

我有以下两种测试方法,它们测试相同的动作方法。第一个失败,第二个通过。这是一个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);            
}
对于失败的测试,我发现action方法正确地返回了null,但是Model对象没有设置为null,而是设置为first product。这真的很神秘…这里发生了什么


[在上面的代码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

我在想这个。。。。但你解释得很好。是,模型未被覆盖。实际上测试是分开的,但我在做一些实验。。。这些代码来自Adam Freeman的Pro Asp.net MVC4。谢谢大卫。。。