N用 ActionName 替换模拟 HttpActionDescriptor
NSubstitute mock HttpActionDescriptor with ActionName
我正在为我的 Web API 控制器编写 AuthorizeAttribute class 一些测试。我正在尝试模拟我需要的一切,以便能够在我的 class AuthorizeAttributeTotalAccess:
中设置以下变量
- actionName = filterContext.ActionDescriptor.ActionName;
- 控制器名称 = filterContext.ControllerContext.ControllerDescriptor.ControllerName;
- claimsPrincipal = HttpContext.Current.User 作为 ClaimsPrincipal;
注意:我没有和HttpContext.Current结婚,如果有另一个 Context thaat 将永远拥有它,请告诉我。
到目前为止,我的测试看起来像:
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Security.Principal;
using System.Threading;
using System.Web.Http;
using System.Web.Http.Controllers;
using BI.Security.Library.Authorization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NSubstitute;
namespace AppTest
{
[TestClass]
public class AttributeAuthorize
{
private AuthorizeAttributeTotalAccess _filter;
private HttpActionContext _actionContext;
private IPrincipal _originalPrincipal;
[TestInitialize]
public void SetUp()
{
var attributes = new Collection<AllowAnonymousAttribute>();
var controllerDescriptor = Substitute.For<HttpControllerDescriptor>();
controllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Returns(attributes);
controllerDescriptor.ControllerName = "Template";
var controllerContext = new HttpControllerContext
{
Request = new HttpRequestMessage(),
ControllerDescriptor = controllerDescriptor
};
// HOW DO I SET ACTIONNAME HERE???
var actionDescriptor = Substitute.For<HttpActionDescriptor>();
actionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Returns(attributes);
_actionContext = new HttpActionContext(controllerContext, actionDescriptor);
_originalPrincipal = Thread.CurrentPrincipal;
_filter = new AuthorizeAttributeTotalAccess();
}
[TestCleanup]
public void TearDown()
{
Thread.CurrentPrincipal = _originalPrincipal;
}
[TestMethod]
public void Returns_unauthorized_response_if_user_is_not_authenticated()
{
_filter.OnAuthorization(_actionContext);
Assert.IsNotNull(_actionContext.Response);
Assert.AreSame(_actionContext.Response.StatusCode, HttpStatusCode.Unauthorized);
}
[TestMethod]
public void Returns_unauthorized_response_if_user_is_authenticated_but_not_in_system_roles()
{
Thread.CurrentPrincipal = GetTestUser("admin");
_filter.OnAuthorization(_actionContext);
Assert.AreSame(_actionContext.Response.StatusCode, HttpStatusCode.Unauthorized);
}
[TestMethod]
public void Short_circuits_request_if_user_is_authenticated_and_in_system_roles()
{
Thread.CurrentPrincipal = GetTestUser("admin", "ApiWriteUser");
_filter.OnAuthorization(_actionContext);
Assert.IsNull(_actionContext.Response);
}
private IPrincipal GetTestUser(params string[] roles)
{
var identity = new ClaimsIdentity(new[] {new Claim(ClaimTypes.Name, "Test User")}, "password");
roles.ToList().ForEach(a => identity.AddClaim(new Claim(ClaimTypes.Role, a)));
var claimsPrincipal = new ClaimsPrincipal(identity);
_actionContext.RequestContext.Principal = claimsPrincipal;
return claimsPrincipal;
}
}
}
我错过了什么?
再说一次,我该如何:
- 设置 ActionName 以便在 class 中可用以进行测试?
- 设置 HttpContext.Current 以便我可以看到用户?
Set the ActionName so it is available in the class to be tested?
我不是 NSubstitute 的专家(阅读:我从未使用过它),但由于你的 HttpActionDescriptor
是一个存根/模拟,你应该能够存根 return 值:
actionDescriptor.ActionName.Return("BLAH");
根据 NSubstitute's documentation,这就是如何计算 属性 的 return 值。
Set the HttpContext.Current so I can see the User?
HttpContext.Current
has a setter, so you should be able to set it to a fake context. Other Stack Overflow answers 演示如何执行此操作。
我正在为我的 Web API 控制器编写 AuthorizeAttribute class 一些测试。我正在尝试模拟我需要的一切,以便能够在我的 class AuthorizeAttributeTotalAccess:
中设置以下变量- actionName = filterContext.ActionDescriptor.ActionName;
- 控制器名称 = filterContext.ControllerContext.ControllerDescriptor.ControllerName;
- claimsPrincipal = HttpContext.Current.User 作为 ClaimsPrincipal;
注意:我没有和HttpContext.Current结婚,如果有另一个 Context thaat 将永远拥有它,请告诉我。
到目前为止,我的测试看起来像:
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Security.Principal;
using System.Threading;
using System.Web.Http;
using System.Web.Http.Controllers;
using BI.Security.Library.Authorization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NSubstitute;
namespace AppTest
{
[TestClass]
public class AttributeAuthorize
{
private AuthorizeAttributeTotalAccess _filter;
private HttpActionContext _actionContext;
private IPrincipal _originalPrincipal;
[TestInitialize]
public void SetUp()
{
var attributes = new Collection<AllowAnonymousAttribute>();
var controllerDescriptor = Substitute.For<HttpControllerDescriptor>();
controllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Returns(attributes);
controllerDescriptor.ControllerName = "Template";
var controllerContext = new HttpControllerContext
{
Request = new HttpRequestMessage(),
ControllerDescriptor = controllerDescriptor
};
// HOW DO I SET ACTIONNAME HERE???
var actionDescriptor = Substitute.For<HttpActionDescriptor>();
actionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Returns(attributes);
_actionContext = new HttpActionContext(controllerContext, actionDescriptor);
_originalPrincipal = Thread.CurrentPrincipal;
_filter = new AuthorizeAttributeTotalAccess();
}
[TestCleanup]
public void TearDown()
{
Thread.CurrentPrincipal = _originalPrincipal;
}
[TestMethod]
public void Returns_unauthorized_response_if_user_is_not_authenticated()
{
_filter.OnAuthorization(_actionContext);
Assert.IsNotNull(_actionContext.Response);
Assert.AreSame(_actionContext.Response.StatusCode, HttpStatusCode.Unauthorized);
}
[TestMethod]
public void Returns_unauthorized_response_if_user_is_authenticated_but_not_in_system_roles()
{
Thread.CurrentPrincipal = GetTestUser("admin");
_filter.OnAuthorization(_actionContext);
Assert.AreSame(_actionContext.Response.StatusCode, HttpStatusCode.Unauthorized);
}
[TestMethod]
public void Short_circuits_request_if_user_is_authenticated_and_in_system_roles()
{
Thread.CurrentPrincipal = GetTestUser("admin", "ApiWriteUser");
_filter.OnAuthorization(_actionContext);
Assert.IsNull(_actionContext.Response);
}
private IPrincipal GetTestUser(params string[] roles)
{
var identity = new ClaimsIdentity(new[] {new Claim(ClaimTypes.Name, "Test User")}, "password");
roles.ToList().ForEach(a => identity.AddClaim(new Claim(ClaimTypes.Role, a)));
var claimsPrincipal = new ClaimsPrincipal(identity);
_actionContext.RequestContext.Principal = claimsPrincipal;
return claimsPrincipal;
}
}
}
我错过了什么?
再说一次,我该如何:
- 设置 ActionName 以便在 class 中可用以进行测试?
- 设置 HttpContext.Current 以便我可以看到用户?
Set the ActionName so it is available in the class to be tested?
我不是 NSubstitute 的专家(阅读:我从未使用过它),但由于你的 HttpActionDescriptor
是一个存根/模拟,你应该能够存根 return 值:
actionDescriptor.ActionName.Return("BLAH");
根据 NSubstitute's documentation,这就是如何计算 属性 的 return 值。
Set the HttpContext.Current so I can see the User?
HttpContext.Current
has a setter, so you should be able to set it to a fake context. Other Stack Overflow answers 演示如何执行此操作。