在这篇博客文章中,我们将学习为各种MVC控制器的行为编写单元测试,例如视图的返回类型,重定向到不同的操作等。具体来说,我们将介绍编写单元测试:
- ViewData的控制器
- TempData的控制器
- ViewBag的控制器
- 视图的控制器
让我们开始吧!
创建MVC项目进行测试
让我们继续创建一个测试中的MVC项目。为了简单起见,我为项目选择了 “无身份验证”。在这个例子中,我们将为HomeController编写单元测试。HomeController包含两个操作方法:
- 索引
- 详细信息
我们将为这些操作编写测试。HomeController包含如下所示的代码:
公共类HomeController: 控制器{ 公共ActionResult索引 (){ return View ("Index" );} 公共ActionResult详细信息 (字符串Id){ // 逻辑来获取详细的ID “详细信息” (返回视图 );}}
创建测试项目
要创建单元测试项目,请右键单击解决方案,然后添加一个新项目。在 “添加新项目” 对话框中,从 “测试” 选项卡中选择 “单元测试项目模板”,如下图所示:
您还可以在创建MVC项目的同时创建测试项目,方法是选中 “添加测试项目” 复选框。创建测试项目后,右键单击该项目并添加对MVC项目的引用。添加后,我们需要在测试项目中添加System.Web.Mvc的引用,方法是右键单击测试项目并选择Manage Nuget Package。从Nuget包管理器中,可以在测试项目中安装Microsoft.AspNet.Mvc。
作为设置测试项目的最后一步,右键单击并添加一个名为HomeControllerTest的类。在新创建的类中,编写一个示例测试方法,如下面的清单所示。
公共类HomeControllerTest{[测试方法] SampleTest () 公共无效{Assert.AreEqual( "HomeController","HomeController" );}}
现在你已经准备好构建测试项目,你不应该得到任何构建错误。我们已经编写了比较两个字符串的示例测试方法,要运行测试,只需选择如下图所示的test->Windows-> test Explorer。
在测试资源管理器中,您会发现SampleTest列在那里。要运行测试,请右键单击测试并选择run,或单击测试顶部的run。在这个例子中,我们运行了SampleTest,它通过!您可以在测试资源管理器中看到通过的测试,如下图所示:
现在让我们开始为HomeController行为编写测试。
测试视图返回的控制器
让我们编写测试来验证预期的视图是否由控制器的操作方法返回,并开始编写一个将失败的测试:
[测试方法]
ReturnsDetailsView () 公共void{HomeController控制器undertest = 新HomeController(); 作为ViewResult的var结果 = controllerUnderTest.Details( "a1" );Assert.AreEqual( "fooview", result.ViewName);}
正如您在上面的测试中看到的,我们正在对HomeController的对象调用Details action。Details操作的返回值作为ViewResult返回。在最后一行,我们断言retuned视图的名称是否等于fooview。在运行测试时,我们将得到如下所示的错误:
正如您在错误消息中清楚地找到的那样,实际的视图名称是Details。因此,让我们回过头来编写要通过的测试。为了使测试通过,我们将预期的视图名称更改为Details。
[测试方法]
ReturnsDetailsView () 公共void{HomeController控制器undertest = 新HomeController(); 作为ViewResult的var结果 = controllerUnderTest.Details( "a1" );Assert.AreEqual( "Details", result.ViewName);}
在上面运行测试将通过。
测试ViewBag返回的控制器
ViewBag、ViewData和TempData是将数据从一个控制器传递到另一个控制器或从控制器传递到视图的对象,如下所示:
- ViewBag将数据从控制器传递到视图
- ViewData将数据从控制器传递到视图
- TempData将数据传递给后续的HTTP请求。
在控制器中,可以设置ViewBag,如下所示:
公共ActionResult详细信息 (字符串Id){ViewBag.Name = "foo"; // 逻辑来获取详细的ID “详细信息” (返回视图 );}
在Details操作中,我们为ViewBag创建一个Name属性,并将其值设置为string foo。测试ViewBag的单元测试可以如下所示编写:
公共无效ReturnsViewBag (){HomeController控制器undertest = 新HomeController(); 作为ViewResult的var结果 = controllerUnderTest.Details( "a1" );Assert.AreEqual( "foo", result.ViewData[ "Name" ]); }
简单地说,我们正在创建控制器的对象,然后调用动作。将返回值转换为ViewResult,然后断言结果。在运行测试,我们会发现它已经通过,控制器返回预期的ViewBag。
测试ViewData返回的控制器
在控制器中,可以设置ViewData,如下所示:
公共ActionResult详细信息 (字符串Id){ ViewData[ "Name"] = "foo"; // 逻辑来获取详细的ID “详细信息” (返回视图 );}
在Details操作中,我们正在创建一个ViewData,并将其值设置为string foo。测试ViewData的单元测试可以如下所示编写:
公共void ReturnsViewData (){HomeController控制器undertest = 新HomeController(); 作为ViewResult的var结果 = controllerUnderTest.Details( "a1" );Assert.AreEqual( "foo", result.ViewData[ "Name" ]);}
简单地说,我们正在创建控制器的对象,然后调用动作。将返回值转换为ViewResult,然后断言结果。在运行测试,我们会发现测试通过,控制器返回预期的ViewData。
测试TempData返回的控制器
TempData用于将数据传递给下一个HTTP请求。简单来说,我们可以使用TempData将数据从一个控制器/动作传递到另一个控制器/动作。它可以设置如下列表所示:
公共ActionResult详细信息 (字符串Id){ TempData[ "Name"] = "foo"; // 逻辑来获取详细的ID 返回 “Index” (RedirectToAction );}
在Details操作中,我们正在创建一个TempData,并将其值设置为string foo并重定向到Index操作。测试TempData的单元测试可以如下所示编写:
[测试方法]
ReturnsTempData () 公共无效{HomeController控制器undertest = 新HomeController(); 作为ViewResult的var结果 = controllerUnderTest.Details( "a1" );Assert.AreEqual( "foo", result.TempData[ "Name" ]);}
在这里,我们创建控制器的对象,然后调用动作。将返回值转换为ViewResult,然后断言结果。在运行测试,我们会发现测试通过,控制器返回预期的TempData。
摘要
为各种控制器的对象编写单元测试总是一个很好的做法。在这篇文章中,我们学习了为以下内容编写单元测试:
- ViewData的控制器
- TempData的控制器
- ViewBag的控制器
- 视图的控制器
我希望你觉得这篇文章有用,感谢阅读!</p