简体   繁体   English

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

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

I have two test methods as below, those are testing the same action method. 我有以下两种测试方法,它们正在测试相同的动作方法。 The first one is failing and second one is passing. 第一个失败,第二个失败。 This is an Asp.net mvc4 application ... Please help me on this ... 这是一个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);            
}

For the failed test, I am finding that the action method is returning null correctly, but somehow the Model object is not set to null, but it is set to first product. 对于失败的测试,我发现该操作方法正确返回了null,但是不知何故Model对象未设置为null,而是将其设置为第一个产品。 which is really mysterious ...What is going on here ... 这真的很神秘...这里发生了什么...

[ In the above code productRepository.Products is of type IQueryable ... and I am using Moq for Mocking] [在上面的代码productRepository.Products类型为IQueryable ...,并且我使用Moq进行模拟]

I'd separate the first test up, but it looks like you already know that and you're just asking for an explanation. 我将第一次测试分开了,但看起来您已经知道了,您只是在要求解释。 From what you describe, the controllers ViewData.Model gets set correctly the first time. 根据您的描述,控制器ViewData.Model首次正确设置。 So target.ViewData.Model is correct. 因此target.ViewData.Model是正确的。 When you set it the second time, perhaps ViewData.Model simply doesn't get overwritten (the framework probably assumes if you're providing null to the view that it can just forget about it because it is null by default). 当您第二次设置它时,也许ViewData.Model根本不会被覆盖(框架可能会假设,如果您向视图提供null ,则默认情况下它会为null而会忘记它)。 Remember within the context of a web app these actions will be called once and then all view data will be thrown away until the next request. 请记住,在Web应用程序的上下文中,这些操作将被调用一次,然后所有视图数据将被丢弃,直到下一个请求。 So next request, ViewData.Model will start off as null again. 因此,下一个请求ViewData.Model将再次以null开头。 So I would only have one controller action test per test method. 因此,每个测试方法只能进行一个控制器动作测试。

I haven't checked this with the source code but it just seems like a likely explanation to me. 我没有检查源代码,但这似乎是对我的可能解释。 You could check what I'm explaining by doing the following. 您可以通过执行以下操作来检查我在解释什么。

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