【发布时间】:2011-01-05 11:29:52
【问题描述】:
我正在编写一个单元测试并调用这样的操作方法
var result = controller.Action(123);
结果是ActionResult,我需要以某种方式获取模型,有人知道该怎么做吗?
【问题讨论】:
我正在编写一个单元测试并调用这样的操作方法
var result = controller.Action(123);
结果是ActionResult,我需要以某种方式获取模型,有人知道该怎么做吗?
【问题讨论】:
在我的 ASP.NET MVC 版本中,Controller 上没有 Action 方法。但是,如果您的意思是 View 方法,那么您可以通过以下方式对结果进行单元测试,以确保结果包含正确的模型。
首先,如果你只从一个特定的Action返回ViewResult,将方法声明为returning ViewResult instead of ActionResult。
例如,考虑这个索引操作
public ViewResult Index()
{
return this.View(this.userViewModelService.GetUsers());
}
您可以像这样轻松访问模型
var result = sut.Index().ViewData.Model;
如果您的方法签名的返回类型是 ActionResult 而不是 ViewResult,则需要先将其强制转换为 ViewResult。
【讨论】:
我们将以下部分放在 testsbase.cs 中,以便在测试中使用类型化模型
ActionResult actionResult = ContextGet<ActionResult>();
var model = ModelFromActionResult<SomeViewModelClass>(actionResult);
ModelFromActionResult...
public T ModelFromActionResult<T>(ActionResult actionResult)
{
object model;
if (actionResult.GetType() == typeof(ViewResult))
{
ViewResult viewResult = (ViewResult)actionResult;
model = viewResult.Model;
}
else if (actionResult.GetType() == typeof(PartialViewResult))
{
PartialViewResult partialViewResult = (PartialViewResult)actionResult;
model = partialViewResult.Model;
}
else
{
throw new InvalidOperationException(string.Format("Actionresult of type {0} is not supported by ModelFromResult extractor.", actionResult.GetType()));
}
T typedModel = (T)model;
return typedModel;
}
使用索引页面和列表的示例:
var actionResult = controller.Index();
var model = ModelFromActionResult<List<TheModel>>((ActionResult)actionResult.Result);
【讨论】:
考虑 a = ActionResult;
ViewResult p = (ViewResult)a;
p.ViewData.Model
【讨论】:
这有点作弊,但在 .NET4 中这样做是一种非常简单的方法
dynamic result = controller.Action(123);
result.Model
今天在单元测试中使用了这个。可能值得进行一些健全性检查,例如:
Assert.IsType<ViewResult>(result);
Assert.IsType<MyModel>(result.Model);
Assert.Equal(123, result.Model.Id);
如果结果将是视图或部分结果,则您可以跳过第一个,具体取决于输入。
【讨论】: