在控制器上调用授权以进行功能测试

本文关键字:功能测试 授权 控制器 调用 | 更新日期: 2023-09-27 18:31:49

在我正在从事的一个项目中,我终于到了为项目的一部分编写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(@"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

在询问我的团队后,有人提到了 MVC 中的ControllerActionInvoker类。 可悲的是,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.
}

在控制器上调用授权以进行功能测试

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

我会使用 Specflow 和 Web 驱动程序来纯粹从浏览器上下文测试场景,即仅通过与网站交互来测试功能。因此,您的"给定"应该使用Web驱动程序来验证用户是否已以"userId"登录,例如通过检查网页上是否存在其名称或类似内容。