1

在我正在进行的一个项目中,我终于可以为项目的一部分编写 SpecFlow 功能测试了。

但是,有一个小问题——我们的应用程序中有一个授权过滤器,我需要为一些测试调用它。

授权过滤器看起来有点像这样(这里有很多编辑)

public class Authorization : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if(filterContext == null
           || filterContext.Controller == null
           || filterContext.Controller.ControllerContext == null)
            throw new ArgumentException("Incomplete filter context.");

        if(! filterContext.Controller.ControllerContext.IsChildAction)
        {
            if(filterContext.RequestContext == null
               || filterContext.RequestContext.HttpContext == null
               || filterContext.RequestContext.HttpContext.Request == null
               || filterContext.RequestContext.HttpContext.Request.Url == null)
                throw new ArgumentException("Incomplete request in filter context.");

            // SNIP: Authorization checks and activities.

            // This one line is a bit tricky to mock...
            HttpRequestBase request = filterContext.HttpContext.Request;

            // SNIP: Other activities that come after   
        }
    }

    // SNIP: Other supporting methods that don't pertain to the problem domain.
}

...在我的功能测试中,我试图在一个特殊的 Given 步骤中调用它:

[Given(@"I am logged in as (.*)")]
public void GivenIAmLoggedInAsX(string userId)
{
    _controller = new SpecificController();
    _controller.ControllerContext = new ControllerContext(new HttpContextMock(), new RouteData(), _controller);

    Authorization authorize = new Authorization();
    AuthorizeContext authContext = new AuthorizationContext(_controller.ControllerContext);
    authorize.OnAuthorization(authContext);

    // SNIP: Other activities that don't pertain to the question.
}

...这不起作用,通过NotImplementedExceptions在我正在构建的测试用例上生成许多。

问了我的团队后,有人提到了ControllerActionInvokerMVC 中的类。可悲的是,MS 文档在细节上有点粗制滥造,例如如何最好地使用它。

此外,StackOverflow在我试图弄清楚如何使用 ControllerActionInvoker 时也失败了。 WayBack Machine也没有太大帮助。

我尝试了几种不同的方法作为临时措施,但没有产生任何结果,而且很沮丧。

问题:我绝对需要在我正在使用的功能测试中调用此过滤器,而直接方法不起作用。为功能测试调用过滤器的最佳方法是什么?

旁注:整个 MVC 过滤系统对我来说是未开发的领域,所以有很多我不知道的。在你的回答中,假设我几乎一无所知,因为这可能是准确的,即使我已经对如何做到这一点进行了研究。

替代实施#1

我发现我的原始示例使用了一个过时的构造函数;推荐使用 2-arg 构造函数。所以,我用它没有什么好的效果。这是它的样子(仍然是直接的方法:)

[Given(@"I am logged in as (.*)")]
public void GivenIAmLoggedInAsX(string userId)
{
    _controller = new RequestFormController();
    _controller.ControllerContext = new ControllerContext(new HttpContextMock(), new RouteData(), _controller);

    Authorization authorize = new Authorization();
    MethodInfo method = typeof (MyController).GetMethod("MyAction");
    ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(typeof(MyController));
    ActionDescriptor actionDescriptor = new ReflectedActionDescriptor(method, "MyAction", controllerDescriptor);
    AuthorizationContext authContext = new AuthorizationContext(_controller.ControllerContext, actionDescriptor);
    authorization.OnAuthorization(authContext);

    // SNIP: Unrelated code.
}
4

1 回答 1

1

根据我的经验,我建议使用单元测试或集成测试来测试 OnAuthorization 的功能。

我将使用 Specflow 和 Web 驱动程序来纯粹从浏览器上下文测试场景,即仅通过与网站交互来测试功能。因此,您的“给定”应该只使用网络驱动程序来验证用户是否以“userId”身份登录,例如通过检查网页上是否存在他们的姓名或类似的东西。

于 2013-09-22T20:45:29.713 回答