C# NSubstitute mock HttpActionDescriptor与ActionName
我正在为我为Web API控制器编写的类编写一些测试。我正在尝试模拟我需要的一切,以便能够在我的类AuthorizeAttributeTotalAccess中设置以下变量:C# NSubstitute mock HttpActionDescriptor与ActionName,c#,asp.net,unit-testing,nsubstitute,C#,Asp.net,Unit Testing,Nsubstitute,我正在为我为Web API控制器编写的类编写一些测试。我正在尝试模拟我需要的一切,以便能够在我的类AuthorizeAttributeTotalAccess中设置以下变量: actionName=filterContext.ActionDescriptor.actionName controllerName=filterContext.ControllerContext.ControllerDescriptor.controllerName claimsPrincipal=HttpContext
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;
}
}
}
使用System.Collections.ObjectModel;
使用System.Linq;
Net系统;
使用System.Net.Http;
使用System.Security.Claims;
使用System.Security.Principal;
使用系统线程;
使用System.Web.Http;
使用System.Web.Http.Controller;
使用BI.Security.Library.Authorization;
使用Microsoft.VisualStudio.TestTools.UnitTesting;
使用替代品;
名称空间AppTest
{
[测试类]
公共类属性授权
{
私有授权属性TotalAccess_过滤器;
私有HttpActionContext\u actionContext;
私人知识产权原原则;
[测试初始化]
公共作废设置()
{
var attributes=新集合();
var controllerDescriptor=替换.For();
controllerDescriptor.GetCustomAttributes()。返回(属性);
controllerDescriptor.ControllerName=“模板”;
var controllerContext=新的HttpControllerContext
{
请求=新建HttpRequestMessage(),
ControllerDescriptor=ControllerDescriptor
};
//如何在此处设置ACTIONNAME???
var actionDescriptor=Substitute.For();
actionDescriptor.GetCustomAttributes().返回(属性);
_actionContext=新的HttpActionContext(controllerContext,actionDescriptor);
_originalPrincipal=Thread.CurrentPrincipal;
_过滤器=新的AuthorizeAttributeTotalAccess();
}
[测试清理]
公共无效拆卸()
{
Thread.CurrentPrincipal=_originalPrincipal;
}
[测试方法]
如果用户未通过身份验证,则public void返回未经授权的响应
{
_过滤.OnAuthorization(_actionContext);
Assert.IsNotNull(_actionContext.Response);
Assert.arame(_actionContext.Response.StatusCode,HttpStatusCode.Unauthorized);
}
[测试方法]
public void返回\u unauthorized\u response\u,如果\u用户\u已\u验证\u但\u未\u在\u系统\u角色()中
{
Thread.CurrentPrincipal=GetTestUser(“admin”);
_过滤.OnAuthorization(_actionContext);
Assert.arame(_actionContext.Response.StatusCode,HttpStatusCode.Unauthorized);
}
[测试方法]
公共无效短路\u请求\u如果\u用户\u已\u验证\u和\u在\u系统中\u角色()
{
Thread.CurrentPrincipal=GetTestUser(“admin”、“ApiWriteUser”);
_过滤.OnAuthorization(_actionContext);
IsNull(_actionContext.Response);
}
私有IPrincipal GetTestUser(参数字符串[]角色)
{
var identity=newclaimsidentity(new[]{newclaim(ClaimTypes.Name,“测试用户”)},“密码”);
roles.ToList().ForEach(a=>identity.AddClaim(新声明(ClaimTypes.Role,a));
var claimsPrincipal=新的claimsPrincipal(标识);
_actionContext.RequestContext.Principal=claimsPrincipal;
返还请求权;
}
}
}
我错过了什么
同样,我如何:
HttpActionDescriptor
是存根/模拟,您应该能够存根返回值:
actionDescriptor.ActionName.Return("BLAH");
根据,这就是如何计算属性的返回值
将HttpContext.Current设置为可以看到用户吗
有一个setter,所以您应该能够将其设置为假上下文。演示如何做到这一点。我在文档中遗漏了这一点。我是新来的。谢谢大家!为了实现它的价值,我宁愿使用
\u actionContext.RequestContext.Principal
,而不是使用HttpContext.Current.User
。这更容易伪造。@vcsjones,如何伪造_actionContext.RequestContext.Principal?