How can I check the ActionFilterAttributes that work with ModelState?

As suggested (among others) by Kazi Manzur Rashid in this blog post , I use ActionFilterAttributes

to transfer model state from one request to another when redirecting.

However, I cannot write a unit test that tests the behavior of these attributes. As an example, this is what I want to check for ImportModelStateAttribute

:

  • Set filterContext

    to TempData[myKey]

    contain some fake "exported" ones ModelState

    (ie ModelStateDictionary

    I create and add one bug myself)
  • Make ModelState

    contain one model error.
  • Challenge OnActionExecuting

    .
  • Make sure the two dictionaries are merged and ModelState

    now contains both errors.

I am at a loss at the very first step.

EDIT:
Yes, I tried mocking ActionFilterAttribute

with Moq, but I am getting errors stating

Invalid setting for a non-dependent member.

for TempData

and ModelState

.

+2


source to share


1 answer


Tomas, you don't need to mock the filterContext, you can create a real object to test the action filter, the same goes for the model state, these are poco objects. The only thing you need to mock is the HttpContext (if needed).



[Fact]
public void Should_import_complete_view_data()
{
    var attribute = new ImportViewDataFromTempDataAttribute();

    var httpContext = new Mock<HttpContextBase>();
    var requestContext = new RequestContext(httpContext.Object, new RouteData());

    var previousModel = new object();
    var previousViewData = new ViewDataDictionary(previousModel) {{"foo", "bar"}};

    previousViewData.ModelState.AddModelError("foo", "bar");

    var controller = new Mock<ControllerBase>();
    controller.Object.ViewData = new ViewDataDictionary();
    controller.Object.TempData = new TempDataDictionary { { attribute.Key, previousViewData } };

    var controllerContext = new ControllerContext(requestContext, controller.Object);
    var actionContext = new ActionExecutingContext(controllerContext, new Mock<ActionDescriptor>().Object, new Dictionary<string, object>());

    attribute.OnActionExecuting(actionContext);

    Assert.True(actionContext.Controller.ViewData.ContainsKey("foo"));
    Assert.True(actionContext.Controller.ViewData.ModelState.ContainsKey("foo"));
    Assert.Same(previousModel, actionContext.Controller.ViewData.Model);
}

      

+8


source







All Articles