【问题标题】:Unit testing an ActionFilter - correctly setting up the ActionExecutingContext单元测试 ActionFilter - 正确设置 ActionExecutingContext
【发布时间】:2010-03-02 22:47:01
【问题描述】:

在自定义ActionFilter 中,我想检查将要执行的控制器操作的属性。通过一个小型测试应用程序运行,在 asp.net 开发服务器中启动应用程序时,以下工作正常-

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();
        }
    }

【问题讨论】:

    标签: unit-testing asp.net-mvc-2 moq action-filter


    【解决方案1】:

    由于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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-20
      • 2016-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-25
      • 1970-01-01
      • 2019-01-28
      相关资源
      最近更新 更多