How to get the Model from an ActionResult?

I'm writing a unit test and I call an action method like this

var result = controller.Action(123);

result is ActionResult and I need to get the model somehow, anybody knows how to do this?

Answers


In my version of ASP.NET MVC there is no Action method on Controller. However, if you meant the View method, here's how you can unit test that the result contains the correct model.

First of all, if you only return ViewResult from a particular Action, declare the method as returning ViewResult instead of ActionResult.

As an example, consider this Index action

public ViewResult Index()
{
    return this.View(this.userViewModelService.GetUsers());
}

you can get to the model as easily as this

var result = sut.Index().ViewData.Model;

If your method signature's return type is ActionResult instead of ViewResult, you will need to cast it to ViewResult first.


We placed the following piece in a testsbase.cs allowing for typed models in the tests a la

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;
}

An example using a Index page and List:

var actionResult = controller.Index();
var model = ModelFromActionResult<List<TheModel>>((ActionResult)actionResult.Result);

consider a = ActionResult;

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

It's somewhat cheating but a very trivial way to do so in .NET4

dynamic result = controller.Action(123);

result.Model

Used this today in a unit test. Might be worth some sanity checks such as:

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

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

You could skip the first one if the result is going to be a view or partial result depending on the input.


Need Your Help

How does extern work in C#?

c# .net performance extern modifier

Whenever I look deeply enough into reflector I bump into extern methods with no source. I read the msdn documentation at http://msdn.microsoft.com/en-us/library/e59b22c5(v=vs.80).aspx. What I got...