gpt4 book ai didi

c# - 单元测试角色访问方法

转载 作者:行者123 更新时间:2023-11-30 12:26:57 25 4
gpt4 key购买 nike

我将如何测试 WebApi/MVC 项目中方法或 Controller 上的授权属性是否具有特定角色

所以我可以测试一个方法来做类似下面的事情?

    [Test]
[TestCase("Put", new []{"Admin","TeamMember"})]
[TestCase("Post", new []{"Admin","TeamMember"})]
[TestCase("Get", new []{"TeamMember"})]

public void Ensure_Methods_have_Correct_Roles(string methodToTest, List<string> roles)
{
var controller = new myController();
Assert.IsTrue(controller.HasRoles(methodToTest, roles));
}

像这样删除 has Roles 扩展方法

    public static bool HasRoles(this Controller controller, string action, string[] roles)
{
var controllerType = controller.GetType();
var method = controllerType.GetMethod(action);

object[] filters = method.GetCustomAttributes(typeof(AuthorizationAttribute), true);

if(!filters.Any(x => x.GetType() == typeof(AuthorizationAttribute))
{
throw exception()
}

var rolesOnCurrentMethodsAttribute = // This is where i'm stuck

foreach(var role in rolesOnCurrentMethodsAttribute)
{
//pseudo-code
if(!roles.contains(role)
{
return false;
}
}
return true;

}

这是否明智,或者我应该直接测试 Controller 操作并测试响应是否为 401/403?不过,这将需要模拟一个上下文,并且意味着需要更多的测试代码,因为我必须分别测试每个方法。

编辑:也许不要关注它是否明智。只是可行吗?

我的想法是,单元测试将是关于什么 Action 应该扮演什么角色的规范规范(因为目前没有书面规范,而且可能永远不会有)。如果开发人员更改角色,则他们需要有充分的理由。

编辑 #2

根据下面 Con 的回答,这就是我最终得到的结果,一种检查 Action 的方法,另一种检查 Controller 的方法。

 public static bool WebApiActionHasRoles(this ApiController controller, string action, string roles)
{
var controllerType = controller.GetType();
var method = controllerType.GetMethod(action);

object[] filters = method.GetCustomAttributes(typeof(System.Web.Http.AuthorizeAttribute), true);

if (!filters.Any())
{
throw new Exception();
}

var rolesOnCurrentMethodsAttribute = filters.SelectMany(attrib => ((System.Web.Http.AuthorizeAttribute)attrib).Roles.Split(new[] { ',' })).ToList();
var rolesToCheckAgainst = roles.Split(',').ToList();

return !rolesOnCurrentMethodsAttribute.Except(rolesToCheckAgainst).Any() && !rolesToCheckAgainst.Except(rolesOnCurrentMethodsAttribute).Any();
}

public static bool WebApiControllerHasRoles(this ApiController controller, string roles)
{
var controllerType = controller.GetType();


object[] filters = controllerType.GetCustomAttributes(typeof(System.Web.Http.AuthorizeAttribute), true);

if (!filters.Any())
{
throw new Exception();
}

var rolesOnCurrentMethodsAttribute = filters.SelectMany(attrib => ((System.Web.Http.AuthorizeAttribute)attrib).Roles.Split(new[] { ',' })).ToList();
var rolesToCheckAgainst = roles.Split(',').ToList();
return !rolesOnCurrentMethodsAttribute.Except(rolesToCheckAgainst).Any() && !rolesToCheckAgainst.Except(rolesOnCurrentMethodsAttribute).Any();
}

如果您想将它与 MVC 而不是 Web Api Controller /操作一起使用,只需将 System.Web.Http.AuthorizeAttribute 更改为 System.Web.MVC.AuthorizeAttribute并在方法签名中将 ApiController 更改为 Controller

最佳答案

如果您指的是 AuthorizeAttributeAuthorizationAttribute,这是您需要的吗:

    public static bool HasRoles(this Controller controller, string action, string[] roles)
{
var controllerType = controller.GetType();
var method = controllerType.GetMethod(action);

object[] filters = method.GetCustomAttributes(typeof(AuthorizeAttribute), true);

if(!filters.Any())
{
throw new Exception();
}

var rolesOnCurrentMethodsAttribute = filters.SelectMany(attrib => ((AuthorizeAttribute)attrib).Roles.Split(new[] { ',' })).ToList();

return roles.Except(rolesInMethod).Count() == 0 && rolesInMethod.Except(roles).Count() == 0;
}

或者,如果您想让测试更严格并且每个操作只执行一个 Authorize 属性:

public static bool HasRoles(this Controller controller, string action, string roles)
{
var controllerType = controller.GetType();
var method = controllerType.GetMethod(action);
var attrib = method.GetCustomAttributes(typeof(AuthorizeAttribute), true).FirstOrDefault() as AuthorizeAttribute;
if (attrib == null)
{
throw new Exception();
}
return attrib.Roles == roles;
}

关于c# - 单元测试角色访问方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27127356/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com