如何测试从Controller Action返回的PartialViewResult对象模型?

时间:2012-07-20 12:27:53

标签: asp.net-mvc unit-testing moq ienumerable asp.net-mvc-partialview

我想为以下控制器操作编写单元测试:

public ActionResult ProductList(int category)
{
    IEnumerable<Product> productList = repository.Products.Where(p => p.CategoryId == category);
    return PartialView("ProductList", productList);
}

这是我的观点:

@model IEnumerable<POS.Domain.Entities.Product>

@foreach (var p in Model)
{
    Html.RenderPartial("_ProductSummary", p);
}

我要测试的是,给定int值categoryProductList操作会返回PartialView productList中的相应值。我不确定如何测试IEnumerable<Product> productList

的值

到目前为止,这是我的单元测试:

[TestMethod]
public void ProductListReturnsAppropriateProducts()
{
    // Arrange
    // - create the mock repository
    Mock<IProductRepository> mock = new Mock<IProductRepository>();
    mock.Setup(m => m.Products).Returns(new Product[] {
    new Product {ProductId = 1, Name = "P1", CategoryId = 1},
    new Product {ProductId = 2, Name = "P2", CategoryId = 2},
    new Product {ProductId = 3, Name = "P3", CategoryId = 1},
    new Product {ProductId = 4, Name = "P4", CategoryId = 2},
    new Product {ProductId = 5, Name = "P5", CategoryId = 3}
    }.AsQueryable());

    // Arrange - create a controller
    ProductController controller = new ProductController(mock.Object);

    // Action
    IEnumerable<Product> result1 = (IEnumerable<Product>)controller.ProductList(1);
    //IEnumerable<Product> result2 = (IEnumerable<Product>)controller.ProductList(2); ???

    // Assert
    Assert.AreEqual(result1, 2);
    // Assert.AreEqual(result2, 2); ???
}

我收到System.InvalidCastException,因为我试图将PartialViewResult投放到IEnumerable - 这就是我被困住的地方。 如何定位控制器中的IEnumerable productList以进行测试?

另外,不测试部分视图是否正确生成是不好的做法? (我假设如果productList值正确,则会正确呈现局部视图)

1 个答案:

答案 0 :(得分:3)

我找到了一个似乎涵盖我需要的解决方案:

/// <summary>
/// Tests that the returned PartialViewResult contains the appropriate products for the selected category
/// First checks that the number of products is correct
/// Then checks that the number of products selected by a specific name is correct, to ensure that the Action did not
/// return products from different categories with the same Product.Name
///</summary>
[TestMethod]
public void ProductListReturnsAppropriateProducts()
{
    // Arrange
    // - create the mock repository
    Mock<IProductRepository> mock = new Mock<IProductRepository>();
    mock.Setup(m => m.Products).Returns(new Product[] {
        new Product {ProductId = 1, Name = "P1", CategoryId = 1},
        new Product {ProductId = 2, Name = "P2", CategoryId = 2},
        new Product {ProductId = 3, Name = "P3", CategoryId = 1},
        new Product {ProductId = 4, Name = "P4", CategoryId = 2},
        new Product {ProductId = 5, Name = "P4", CategoryId = 3}
    }.AsQueryable());

    // Arrange - create a controller
    ProductController controller = new ProductController(mock.Object);

    // Action
    PartialViewResult result = (PartialViewResult) controller.ProductList(2);

    // Assert
    Assert.AreEqual(((IEnumerable<Product>)result.ViewData.Model).Count(), 2);
    Assert.IsTrue(((IEnumerable<Product>)result.ViewData.Model).Count(o => o.Name == "P4") == 1);
}

我将有几个PartialViewResult值 - 但我开始遇到同时测试多个Controller Action结果的问题。