2010-03-02 148 views
4

在自定義ActionFilter中,我想檢查將要執行的控制器操作的屬性。通過一個小的測試應用程序中運行,啓動在asp.net開發應用程序時,以下工作服務器 -單元測試ActionFilter - 正確設置ActionExecutingContext

public class CustomActionFilterAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     var someAttribute = filterContext.ActionDescriptor 
            .GetCustomAttributes(typeof(SomeAttribute), false) 
            .Cast<SomeAttribute>() 
            .SingleOrDefault(); 

     if (someAttribute == null) 
     { 
      throw new ArgumentException(); 
     } 

     // do something here 
    } 

    public override void OnActionExecuted(ActionExecutingContext filterContext) 
    { 
     // ... 
    } 
} 

沒有SomeAttribute的行動方法拋出ArgumentException,相反,與SomeAttribute操作方法沒有。到現在爲止還挺好。

現在我想爲ActionFilter設置一些單元測試,但是如何設置OnActionExecuting方法應該在單元測試中運行的操作方法?使用以下代碼沒有找到要執行的操作方法的SomeAttribute。測試設置是否正確?我有沒有在測試中正確安排一些內容?爲了澄清,該測試是不完整的,但我不知道我在OnActionExecuting在測試錯過這樣someAttributenull

[TestMethod] 
    public void Controller_With_SomeAttribute() 
    { 
     FakeController fakeController = 
      new FakeController(); 

     ControllerContext controllerContext = 
      new ControllerContext(new Mock<HttpContextBase>().Object, 
            new RouteData(), 
            fakeController); 

     var actionDescriptor = new Mock<ActionDescriptor>(); 
     actionDescriptor.SetupGet(x => x.ActionName).Returns("Action_With_SomeAttribute"); 

     ActionExecutingContext actionExecutingContext = 
      new ActionExecutingContext(controllerContext, 
             actionDescriptor.Object, 
             new RouteValueDictionary()); 

     CustomActionFilterAttribute customActionFilterAttribute = new CustomActionFilterAttribute(); 
     customActionFilterAttribute.OnActionExecuting(actionExecutingContext); 
    } 

    private class FakeController : Controller 
    { 
     [SomeAttribute] 
     ActionResult Action_With_SomeAttribute() 
     { 
      return View(); 
     } 
    } 

回答

5

由於ActionExecutingContext的ActionDescriptor財產是虛擬的,你可以說override並提供您自己的實施ActionDescriptor

下面是通過目前執行的OnActionExecuting驗證兩個分支兩項測試:

[ExpectedException(typeof(ArgumentException))] 
[TestMethod] 
public void OnActionExecutingWillThrowWhenSomeAttributeIsNotPresent() 
{ 
    // Fixture setup 
    var ctxStub = new Mock<ActionExecutingContext>(); 
    ctxStub.Setup(ctx => ctx.ActionDescriptor.GetCustomAttributes(typeof(SomeAttribute), false)) 
     .Returns(new object[0]); 

    var sut = new CustomActionFilterAttribute(); 
    // Exercise system 
    sut.OnActionExecuting(ctxStub.Object); 
    // Verify outcome (expected exception) 
    // Teardown 
} 

[TestMethod] 
public void OnActionExecutingWillNotThrowWhenSomeAttributeIsPresent() 
{ 
    // Fixture setup 
    var ctxStub = new Mock<ActionExecutingContext>(); 
    ctxStub.Setup(ctx => ctx.ActionDescriptor.GetCustomAttributes(typeof(SomeAttribute), false)) 
     .Returns(new object[] { new SomeAttribute() }); 

    var sut = new CustomActionFilterAttribute(); 
    // Exercise system 
    sut.OnActionExecuting(ctxStub.Object); 
    // Verify outcome (no exception indicates success) 
    // Teardown 
}