在控制器上调用授权以进行功能测试
本文关键字:功能测试 授权 控制器 调用 | 更新日期: 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"登录,例如通过检查网页上是否存在其名称或类似内容。