Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NSubstitute mock HttpActionDescriptor与ActionName_C#_Asp.net_Unit Testing_Nsubstitute - Fatal编程技术网

C# NSubstitute mock HttpActionDescriptor与ActionName

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

我正在为我为Web API控制器编写的类编写一些测试。我正在尝试模拟我需要的一切,以便能够在我的类AuthorizeAttributeTotalAccess中设置以下变量:

  • actionName=filterContext.ActionDescriptor.actionName
  • controllerName=filterContext.ControllerContext.ControllerDescriptor.controllerName
  • claimsPrincipal=HttpContext.Current.User作为claimsPrincipal 注意:我没有与HttpContext结婚。当前,如果有其他Context,请随时通知我

    到目前为止,我的测试如下:

    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;
    返还请求权;
    }
    }
    }
    
    我错过了什么

    同样,我如何:

  • 设置ActionName,使其在要测试的类中可用
  • 设置HttpContext.Current的
  • 设置ActionName,使其在要测试的类中可用

    我不是NSubstitute方面的专家(请阅读:我从未使用过它),但由于您的
    HttpActionDescriptor
    是存根/模拟,您应该能够存根返回值:

    actionDescriptor.ActionName.Return("BLAH");
    
    根据,这就是如何计算属性的返回值

    将HttpContext.Current设置为可以看到用户吗


    有一个setter,所以您应该能够将其设置为假上下文。演示如何做到这一点。

    我在文档中遗漏了这一点。我是新来的。谢谢大家!为了实现它的价值,我宁愿使用
    \u actionContext.RequestContext.Principal
    ,而不是使用
    HttpContext.Current.User
    。这更容易伪造。@vcsjones,如何伪造_actionContext.RequestContext.Principal?