单元测试根据模型的方法

时间:2014-01-06 11:55:35

标签: unit-testing asp.net-mvc-4

我正在研究我的MVC 4应用程序的单元测试。下面是我想要进行单元测试的方法之一: -

    [HttpPost]
    public ActionResult Index(ProductViewModel model)
    {
        if (model != null)
        {

            return PartialView("_ProductGrid", SearchProduct(model));
        }
        else
        {
            return RedirectToAction("Index");
        }
    }

我已经为此编写了单元测试方法但是当我通过代码覆盖率选项检查它的代码覆盖率时,其他部分显示未覆盖。但我不确定原因。

任何人都可以帮我解决这个问题吗?

以下是我的测试方法的代码:

    [TestMethod]
    public void IndexPostTest()
    {
        // Arrange
        const string searchInDescription = "all";

        ProductController controller = new ProductController();
        ProductViewModel model = new ProductViewModel
        {
            SearchA = true,
            SearchB= true,
            SearchIC = true,
            Description = searchInDescription
        };

        TestControllerBuilder builder = new TestControllerBuilder();
        builder.InitializeController(controller);

        // Act           
        var result = controller.Index(model) as ActionResult;

        var viewmodel = (ProductViewModel)((ViewResultBase)(result)).Model;

        int matches = _productService.LookupA("", searchInDescription).Count +
                      _productService.LookupB("", searchInDescription).Count +
                      _ProductService.LookupC("", searchInDescription).Count;

        if (result != null && viewmodel != null && result.GetType() == typeof(PartialViewResult))
        {
            // Assert
            Assert.IsNotNull(result);
            Assert.IsInstanceOfType(viewmodel, typeof(ProductViewModel));

            if (viewmodel.Products != null)
                Assert.AreEqual(matches, viewmodel.Products.Count());
            if (matches > 0 && viewmodel.Products != null && viewmodel.Products.ToList().Count > 0 && viewmodel.Products.ToList()[0].Description != "")
            {
                Assert.IsTrue(viewmodel.Products.ToList()[0].Description.ToUpper().Contains(searchInDescription.ToUpper()));
            }
        }
        else if (result != null && result.GetType() == typeof(RedirectResult))
        {
            var redirectResult = result as RedirectResult;
            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual("Index", redirectResult.Url);

        }
    }

2 个答案:

答案 0 :(得分:2)

不要在测试中使用条件逻辑。决不。当你多次运行它时,测试应该返回相同的结果,它应该验证单个事物。所以,你实际上应该有两个测试 - 一个验证模型有效的情况(你有那个测试),另一个验证模型无效的情况(你没有测试,因为你提供了有效的模型) )。

首先测试的是有效模型:

[TestMethod]
public void ShouldProvideProductGridWhenModelIsNotNull()
{
    // Arrange        
    ProductController controller = new ProductController();
    ProductViewModel model = new ProductViewModel
    {
        SearchA = true,
        SearchB= true,
        SearchIC = true,
        Description = searchInDescription
    };

    // ... other arrange code

    // Act           
    var result = (PartialViewResult)controller.Index(model);

    // Assert
    Assert.IsNotNull(result);
    var viewmodel = (ProductViewModel)result.Model;
    // ... other assertions
}

第二次重定向测试:

[TestMethod]
public void ShouldRedirectToIndexWhenModelIsNull()
{
    // Arrange        
    ProductController controller = new ProductController();      

    // ... other arrange code

    // Act           
    var result = (RedirectToActionResult)controller.Index(null);

    // Assert
    Assert.IsNotNull(result);
    Assert.AreEqual("Index", redirectResult.Url);
}

答案 1 :(得分:2)

您只使用非空的模型测试Index操作。因此,else操作的Index部分永远不会从您的测试中调用。

您需要进行两项测试。一个测试模型何时为空,一个测试时为空。

[TestMethod]
public void IndexPost_NotNull()
{
    // TODO: Setup test data as you have done

    // Act           
    var result = controller.Index(model) as ActionResult;

    // Assert
    // TODO: check result is a partial view result
}

[TestMethod]
public void IndexPost_Null()
{
    // Act           
    var result = controller.Index(null) as ActionResult;

    // Assert
    // TODO: check result is a redirect result
}