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

时间:2013-12-21 07:29:03

标签: 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);           
    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,但它被设置为第一个产品。这真的很神秘......这里发生了什么......

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

1 个答案:

答案 0 :(得分:0)

我将第一次测试分开,但看起来你已经知道了,而你只是在寻求解释。根据您的描述,控制器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