为ASP.NET MVC应用程序创建单元测试 - TOMMYHU - 专注互联网开发及运营技术,提供相关资料及软件下载,奇趣网络时事评论!
Apr 2

为ASP.NET MVC应用程序创建单元测试 不指定

本教程的目的是解释如何为 ASP.NET MVC 应用程序中的控制器编写单元测试。我们将讨论如何创建三种不同类型的单元测试。您将了解如何测试控制器操作返回的视图、如何测试控制器操作返回的视图数据,以及如何测试一个控制器操作是否重定向到另一个控制器操作。

创建测试控制器

我们首先创建要测试的控制器。程序清单 1 中包含名称为 ProductController 的控制器。

程序清单 1 ProductController.cs

                                    
using System;
            using System.Web.Mvc;            

namespace Store.Controllers
            {
                public class ProductController : Controller
                {
                      public ActionResult Index()
                      {
                          // Add action logic here
                          throw new NotImplementedException();
                      }

            

          public ActionResult Details(int Id)
                      {
                          return View("Details");
                      }
                }
            }

            

HomeController 包含两个操作方法,名称为 Index() 和 Details()。两个操作方法都返回一个视图。请注意, Details() 操作接受名称为 Id 的参数。

测试控制器返回的视图

假设要测试 ProductController 是否返回正确的视图。希望确保当激活 ProductController.Details() 操作时,返回 Details 视图。程序清单 2 中的测试类包含一个单元测试,用于测试由 ProductController.Details() 操作返回的视图。

程序清单 2 ProductControllerTest.cs

                                    
using System.Web.Mvc;
            using Microsoft.VisualStudio.TestTools.UnitTesting;
            using Store.Controllers;            

namespace StoreTests.Controllers
            {
                [TestClass]
                public class ProductControllerTest
                {
                      [TestMethod]
                      public void TestDetailsView()
                      {
                          var controller = new ProductController();
                          var result = controller.Details(2) as ViewResult;
                          Assert.AreEqual("Details", result.ViewName);
                      }
                }
            }

            

程序清单 2 中的类包含名称为 TestDetailsView() 的测试方法。此方法包括三行代码。第一行代码创建一个 ProductController 类的新实例。第二行代码激活控制器的 Details() 操作方法。最后一行代码检查 Details() 操作返回的是否是 Details 视图。

ViewResult.ViewName 属性代表由控制器返回的视图的名称。测试该属性时需要特别小心。控制器返回视图有两种方法。控制器可以显式地返回视图,如下所示:

                                    
public ActionResult Details(int Id)
            {
                return View("Details");
            }

另外,视图的名称可以引用控制器操作的名称,如下所示:

                                    
public ActionResult Details(int Id)
            {
                return View();
            }

此控制器操作也返回名称为 Details 的视图。然而,视图的名称引用自操作的名称。如果想要测试视图名称,则必须显式地从控制器操作返回视图名称。

通过按 Ctrl-R,A 组合键或单击 Run All Tests in Solution 按钮(如图 1 所示),可以运行程序清单 2 中的单元测试。如果通过测试,则将看到如图 2 所示的 Test Results 窗口。

图 1:运行解决方案中的所有测试

图 2:成功!

测试控制器返回的 View Data

MVC 控制器使用 View Data 将数据传递给视图。例如,假设想要在激活 ProductController Details() 操作时显示某个产品的详细信息。在这种情况下,可以创建 Product 类的实例(在模型中定义),然后利用 View Data 将实例传递给 Details 视图。

程序清单 3 中修改后的 ProductController 包含更新的 Details() 操作,它返回 Product。

程序清单 3 ProductController.cs

                                    
            
using System;using System.Web.Mvc;namespace Store.Controllers{     public class ProductController : Controller     {          public ActionResult Index()          {               // Add action logic here               throw new NotImplementedException();          }          public ActionResult Details(int Id)          {               var product = new Product(Id, "Laptop");               return View("Details", product);          }     }}
            

首先,Details() 操作创建 Product 类的新实例表示笔记本电脑。接下来,Product 类的实例被作为第二个参数传递给 View() 方法。

可以编写测试单元测试预期的数据是否包含在视图数据中。程序清单 4 中的单元测试用于测试表示笔记本电脑的 Product 是否在调用 ProductController Details() 操作方法时返回。

程序清单 4 ProductControllerTest.cs

                                    
            
using System.Web.Mvc;using Microsoft.VisualStudio.TestTools.UnitTesting;using Store.Controllers;namespace StoreTests.Controllers{     [TestClass]     public class ProductControllerTest     {          [TestMethod]          public void TestDetailsViewData()          {               var controller = new ProductController();               var result = controller.Details(2) as ViewResult;               var product = (Product) result.ViewData.Model;               Assert.AreEqual("Laptop", product.Name);          }     }}
            

在程序清单 4 中,TestDetailsView() 方法通过激活 Details() 方法测试返回的 View Data。ViewData 公开为 ViewResult(通过激活 Details() 方法返回)上的一个属性。ViewData.Model 属性包含传递给视图的产品。测试只是简单地验证包含在 View Data 中的产品名称是 Laptop。

测试控制器返回的操作结果

较复杂的控制器操作可能返回不同类型的操作结果,具体取决于传递给控制器操作的参数值。控制器操作可以返回各种类型的操作结果,包括 ViewResult、RedirectToRouteResult 或 JsonResult。

例如,程序清单 5 中修改的 Details() 操作在将有效 Id 传递给操作时返回 Details 视图。如果传递无效的产品 Id(Id 的值小于 1),则将重定向到 Index() 操作。

程序清单 5 ProductController.cs

                                    
            
using System;using System.Web.Mvc;namespace Store.Controllers{     public class ProductController : Controller     {          public ActionResult Index()          {               // Add action logic here               throw new NotImplementedException();          }          public ActionResult Details(int Id)          {               if (Id < 1)                    return RedirectToAction("Index");               var product = new Product(Id, "Laptop");               return View("Details", product);          }     }}
            

可以使用程序清单 6 中的单元测试来测试 Details() 操作的行为。程序清单 6 中的单元测试验证当 Id 值 -1 被传递到 Details() 方法时是否重定向到 Index 视图。

程序清单 6 ProductControllerTest.cs

                                    
            
using System.Web.Mvc;using Microsoft.VisualStudio.TestTools.UnitTesting;using Store.Controllers;namespace StoreTests.Controllers{     [TestClass]     public class ProductControllerTest     {          [TestMethod]          public void TestDetailsRedirect()          {               var controller = new ProductController();               var result = (RedirectToRouteResult) controller.Details(-1);               Assert.AreEqual("Index", result.Values["action"]);          }     }}
            

在调用控制器操作的 RedirectToAction() 方法时,控制器操作返回 RedirectToRouteResult。测试用于检查 RedirectToRouteResult 是否将用户重定向到名称为 Index 的控制器操作。

总结

在本教程中,我们学习了如何为 MVC 控制器操作构建单元测试。首先,我们学习了如何验证控制器操作是否返回正确的视图。学习了如何使用 ViewResult.ViewName 属性验证视图的名称。

接下来,我们研究了如何测试 View Data 的内容。学习了如何检查调用控制器操作后 View Data 中是否返回正确的产品。

最后,我们讨论了如何测试控制器操作是否返回不同类型的操作结果。学习了如何测试控制器操作是返回 ViewResult 还是 RedirectToRouteResult。


▲返回顶部
Last modified by tommyhu on2012/04/02 19:24

Add a comment

Nickname

emotemotemotemotemotemotemotemotemotemotemotemotemotemotemotemot