2016-04-14 71 views
6

sto cercando di testare il seguente filtro:Come simulare ActionExecutingContext con Moq?

using Microsoft.AspNet.Mvc; 
using Microsoft.AspNet.Mvc.Filters; 

namespace Hello 
{ 
    public class ValidationFilter : ActionFilterAttribute 
    { 
     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      if (!filterContext.ModelState.IsValid) { 
       filterContext.Result = new BadRequestObjectResult(filterContext.ModelState); 
      } 
     } 
    } 
} 

Sto cercando di prendere in giro l'ActionFilterAttribute utilizzando Moq.

Sto usando Mvc 6.0.0-rc1

Il mio primo tentativo:

var context = new ActionExecutingContext(
        new ActionContext(Mock.Of<HttpContext>(), new RouteData(), new ActionDescriptor()), 
        new IFilterMetadata[] { filter, }, 
        new Dictionary<string, object>(), 
        controller: new object()); 

Ma non potevo ignorare il ModelState. Sembra di essere in sola lettura: https://github.com/aspnet/Mvc/blob/6.0.0-rc1/src/Microsoft.AspNet.Mvc.Abstractions/ActionContext.cs#L25

Poi ho provato:

var contextMock = new Mock<ActionExecutingContext>(
        new ActionContext(Mock.Of<HttpContext>(), new RouteData(), new ActionDescriptor()), 
        new IFilterMetadata[] { filter, }, 
        new Dictionary<string, object>()); 

Ma quando chiamo filter.OnActionExecuting(contextMock.Object) ricevo il seguente errore:

Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: Microsoft.AspNet.Mvc.Filters.ActionExecutingContext. 
     Could not find a constructor that would match given arguments: 
     Microsoft.AspNet.Mvc.ActionContext 
     Microsoft.AspNet.Mvc.Filters.IFilterMetadata[] 
     System.Collections.Generic.Dictionary`2[System.String,System.Object] 

Come testare un filtro che utilizza ModelState?

risposta

9

Mi sono appena imbattuto nello stesso problema e l'ho risolto in questo modo.

[Fact] 
public void ValidateModelAttributes_SetsResultToBadRequest_IfModelIsInvalid() 
{ 
    var validationFilter = new ValidationFilter(); 
    var modelState = new ModelStateDictionary(); 
    modelState.AddModelError("name", "invalid"); 

    var actionContext = new ActionContext(
     new Mock<HttpContext>().Object, 
     new Mock<RouteData>().Object, 
     new Mock<ActionDescriptor>().Object, 
     modelState 
    ); 

    var actionExecutingContext = new ActionExecutingContext(
     actionContext, 
     new List<IFilterMetadata>(), 
     new Dictionary<string, object>(), 
     new Mock<Controller>().Object 
    ); 

    validatationFilter.OnActionExecuting(actionExecutingContext); 

    Assert.IsType<BadRequestObjectResult>(actionExecutingContext.Result); 
}