2011-03-04 59 views
0

所以我重写OnAction在我的BaseController类中执行以设置BaseViewModel的CurrentUser属性。我想能够单元测试这个,但不知道如何。如何测试OnActionExecuted过滤器?

下面的代码:

protected override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     if (filterContext.Result is ViewResult && ((ViewResult)filterContext.Result).ViewData.Model != null) 
     { 
      ((BaseViewModel)((ViewResult)filterContext.Result).ViewData.Model).CurrentUser = CurrentUser; 
     } 

     base.OnActionExecuted(filterContext); 
    } 

而这里的测试:

BaseController controller = new BaseController(); 
Mock<ActionExecutedContext> MockActionExecutedContext = new Mock<ActionExecutedContext>(); 
MockActionExecutedContext.Setup(ctx => ctx.Result).Returns(new ViewResult()); 
controllerAccessor.OnActionExecuted(MockActionExecutedContext.Object); 

ViewResult vr = MockActionExecutedContext.Object.Result as ViewResult; 
BaseViewModel model = vr.ViewData.Model as BaseViewModel; 
User currentUser = model.CurrentUser; 
Assert.NotNull(currentUser); 

当我运行测试,我发现了错误:

System.NotSupportedException : Invalid setup on a non-virtual member: ctx => ctx.Result 

我知道我只能在每个派生控制器的单元测试中测试属性,但必须有一个更简洁的方法来完成此操作。有任何想法吗?

回答

3

我不认为你需要模拟ActionExecutedContext。只需创建一个实际的ActionExecutedContext传递给你的控制器。我已经采取了一些自由,但考虑这个控制器代码:

public class BaseController : Controller 
{ 
    public User CurrentUser { get; set; } 

    protected override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     if (filterContext.Result is ViewResult && ((ViewResult)filterContext.Result).ViewData.Model != null) 
     { 
      ((BaseViewModel)((ViewResult)filterContext.Result).ViewData.Model).CurrentUser = CurrentUser; 
     } 

     base.OnActionExecuted(filterContext); 
    } 

    public void controllerAccessor(ActionExecutedContext filterContext) 
    { 
     OnActionExecuted(filterContext); 
    } 
} 

而这个测试代码,这是工作我的机器上:

[TestMethod] 
    public void YourTest() 
    { 
     // Arrange 
     var inUser = new User(); 
     BaseController controller = new BaseController() { CurrentUser = inUser }; 
     var ctx = new ActionExecutedContext(); 
     var inVr = new ViewResult(); 
     var baseVm = new BaseViewModel(); 
     inVr.ViewData.Model = baseVm; 
     ctx.Result = inVr; 

     // Act 
     controller.controllerAccessor(ctx); 

     // Assert 
     ViewResult outVr = (ViewResult)ctx.Result; 
     BaseViewModel model = (BaseViewModel)outVr.ViewData.Model; 
     User outUser = model.CurrentUser; 
     Assert.AreEqual(inUser, outUser); 
    } 
相关问题