如何从ActionResult获取模型?

时间:2010-01-15 11:31:50

标签: asp.net-mvc unit-testing

我正在编写一个单元测试,我称这样的动作方法

var result = controller.Action(123);

结果是ActionResult,我需要以某种方式得到模型,有谁知道如何做到这一点?

4 个答案:

答案 0 :(得分:33)

在我的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。

答案 1 :(得分:16)

我们将以下部分放在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);

答案 2 :(得分:10)

考虑a = ActionResult;

ViewResult p = (ViewResult)a;
p.ViewData.Model

答案 3 :(得分:2)

这有点欺骗,但在.NET4中这是一个非常简单的方法

dynamic result = controller.Action(123);

result.Model

今天在单元测试中使用它。可能值得进行一些健全性检查,例如:

Assert.IsType<ViewResult>(result); 
Assert.IsType<MyModel>(result.Model);

Assert.Equal(123, result.Model.Id);

如果结果将是视图或部分结果,您可以跳过第一个,具体取决于输入。