我在我的标准上做了一些简单的MS单元测试,没有特殊的控制器。
当我从返回的ViewResult对象检查ViewName属性时,它是"" (空)。
我的印象是ViewName是由View的名称隐含的(就像suggested by this MS article on ASP.NET MVC控制器测试)。
顺便说一句,当我测试ViewData时,它都在那里并且是正确的。
这是我的代码。
public ActionResult Index(int? page, string tag)
{
if (page == null || page <= 0)
{
page = 1;
}
var viewData = new IndexViewData
{
... my property setters, etc ...
};
return View(viewData);
}
[TestMethod]
public void Index_Action_Should_Return_Index_View_For_Default_HomePage()
{
// Arrange.
var controller = PostController; // Wrapper, cause I use D.I.
// Act.
ViewResult viewResult = controller.Index(null, null) as ViewResult;
// Assert.
Assert.IsNotNull(viewResult);
Assert.AreEqual("Index", viewResult.ViewName); // This is false/fails.
var indexViewData = viewResult.ViewData.Model as IndexViewData;
Assert.IsNotNull(indexViewData); // This is true.
}发布于 2009-04-05 14:07:06
仅当您在ViewResult中进行设置时,才会显示ViewName。如果您的视图名称与控制器名称匹配,那么我将检查以确保ViewName为null或空,因为这将是正确的行为,因为您不希望在视图上设置名称。我只在希望返回的视图与操作不匹配时才检查是否设置了ViewName --例如,当返回"Error“视图时。
编辑:以下是ExecuteResult在ViewResultBase.cs中的源代码(来自RC1,我的Macintosh上没有RTW的源代码)。正如您所看到的,它检查ViewName是否已被直接设置,如果没有,它将其从控制器上下文的路由数据中的操作中提取出来。这只发生在ExecuteResult中,它是在控制器的操作完成后调用的。
public override void ExecuteResult(ControllerContext context) {
if (context == null) {
throw new ArgumentNullException("context");
}
if (String.IsNullOrEmpty(ViewName)) {
ViewName = context.RouteData.GetRequiredString("action");
}
ViewEngineResult result = null;
if (View == null) {
result = FindView(context);
View = result.View;
}
ViewContext viewContext = new ViewContext(context, View, ViewData, TempData);
View.Render(viewContext, context.HttpContext.Response.Output);
if (result != null) {
result.ViewEngine.ReleaseView(context, View);
}
}发布于 2010-12-07 07:15:52
我个人发现MVC2提供的测试工具有点笨拙。我猜已经存在了一些更好的东西,但我最终创建了一个简单的类来测试操作。我在一个名为MockRoundTrip的优秀开源Java MVC framework Stripes提供的类上对接口进行了建模(实现是另一回事)。
下面是在测试操作时用于获取操作目标页面的方法,称为getTripDestination()。无论是否显式设置了视图名称,它都会返回正确的结果
//Get the destination page of the request, using Runtime execution pattern of MVC, namely
//if no ViewName is explicitly set in controller, ViewResult will have an empty ViewName
//Instead, current action name will be used in its place
public string getTripDestination()
{
RouteData routeData = getRouteData();
ViewResult viewResult = (result is ViewResult) ? (ViewResult)result : null;
string tripDestination = (viewResult != null) ? viewResult.ViewName : "";
return (tripDestination != "") ? tripDestination : (String)routeData.Values["action"];
}
private RouteData getRouteData()
{
HttpContextBase context = controller.ControllerContext.RequestContext.HttpContext;
return RouteTable.Routes.GetRouteData(context);
}发布于 2009-04-24 22:33:41
视图名称由框架自动设置。但是当我们进行单元测试时,我们缩短了框架的路径,并且没有留下任何东西来设置名称。
因此,在进行单元测试时,我们的操作需要显式地设置视图名称。如果我们真的真的想要依赖于约定,我们也可以检查null或null。
https://stackoverflow.com/questions/718464
复制相似问题