我正在尝试使用C#中的NUnit对自定义授权属性进行单元测试。特别是在未被授权的情况下,返回了特定的HTTP状态码和消息。
我的属性非常简单-代码如下:
public class AuthorizationAttribute : AuthorizeAttribute
{
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (IsAuthorized(actionContext))
return;
HandleUnauthorizedRequest(actionContext);
}
protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
{
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Forbidden, "You are not authorized to access this resource");
}
}
所以为了测试这个(目前测试领域内较新的东西),我拼凑了以下代码。其中,我附加了一个通用的身份,包括用户名和一些角色数据。
public void Given_UserIsNotInAuthorizedRoles_When_Auhtorizing_ReturnsForbidden()
{
// Arrange
IPrincipal principal = new GenericPrincipal(new GenericIdentity("TestName"), new[] { "TestRole" });
HttpActionContext mockActionContext = new HttpActionContext()
{
ControllerContext = new HttpControllerContext()
{
Request = new HttpRequestMessage(),
RequestContext = new HttpRequestContext() { Principal = principal }
},
ActionArguments = { { "SomeArgument", "null" } }
};
mockActionContext.ControllerContext.Configuration = new HttpConfiguration();
mockActionContext.ControllerContext.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
// Act
AuthorizationAttribute authAttr = new AuthorizationAttribute();
authAttr.OnAuthorization(mockActionContext);
// Assert
Assert.IsTrue(mockActionContext.Response.StatusCode == System.Net.HttpStatusCode.Forbidden);
}
模拟控制器长这样:
[Authorization(Roles = "AdminRoleOnly", Users = "A user")]
internal class MockController : ApiController { }
当我在调试时,发现
if(IsAuthorized(actionContext))
返回了true
,这一点令我难以理解。请问有人能指导我为什么我的授权属性会将此标识符视为有效吗?
值得一提的是,该代码在生产环境中可用。我正在补充一些测试。
与此有关的内容如下:
我已经阅读了一个类似问题的问题和答案ASP.NET MVC unit testing custom AuthorizeAttribute,尽管两者都不能正常工作或相关,特别是因为它们是针对MVC控制器而不是Api Controllers的。
我还阅读并尝试实现了这个问题的答案中的代码Mocking HttpActionContext.ActionArguments when testing Web.Api ActionFilter
后一个方法使我接近成功,因为我的授权属性正在测试中触发,我可以传递所需的上下文信息。
authAttr.OnAuthorization(mockActionContext);
中,我遇到了错误 "Object reference not set to an instance of an object",不确定我做错了什么? - zeroflaw