簡體   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