MVC自定义过滤器,手动调用ASP.NET管道事件进行单元测试

时间:2011-12-23 09:37:52

标签: asp.net asp.net-mvc-3 unit-testing events protected

public abstract class MyControllerBase : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext context)
    {
        // do some magic
    }
}

我的所有控制器都继承自MyControllerBase。问题是现在我无法对某些方法进行单元测试,因为过滤器会设置一些影响代码路径的授权/逻辑标志。

有没有办法手动触发OnActionExecuting?管道如何触发这些事件?

编辑,以便在回应评论时更多地展示此设计背后的想法。我基本上有类似的东西:

public abstract class MyControllerBase : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext context)
    {
        UserProperties = 
             _userService
                .GetUserProperties(filterContext.HttpContext.User.Identity.Name);

        ViewBag.UserProperties = UserProperties;
    }

    public UserProperties { get; private set; }

    public bool CheckSomethingAboutUser()
    {
         return UserProperties != null 
            && UserProperties.IsAuthorisedToPerformThisAction;
    }

    // ... etc, other methods for querying UserProperties
}

所以现在ViewController中的任何地方我都可以获得当前用户的详细信息,他们的电子邮件,他们拥有的授权,他们所在的部门等。

示例:

public class PurchasingController : MyControllerBase 
{
    public ActionResult RaisePurchaseOrder(Item item)
    {
        // can use UserProperties from base class to determine correct action...

        if (UserProperties.CanRaiseOrders)

        if (UserProperties.Department == item.AllocatedDepartment)
    }
}

所以这个设计非常好用,但是你可以看到测试上面的动作很困难,因为我不能直接操作测试设置中的UserProperties

1 个答案:

答案 0 :(得分:2)

我不确定你是否想要在MCV中覆盖OnActionExecuting,通常我会ActionFilterAttribute

public class SomeMagicAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {

    }
}

然后你的班级:

[SomeMagic]
public abstract class MyControllerBase : Controller
{

}

然后在你的单元测试中你可以做到

var magic = new SomeMagicAttribute();
var simulatedContext = new ActionExecutingContext();
magic.OnActionExecuting(simulatedContext);