asp.net mvc 3-更新:在ReSharper单元测试中将HttpContext和IPrincipal传递给Co



我正试图在ASP MVC控制器上运行几个基本的单元测试,但在某一点上,控制器需要检查IPrincipal User对象,如下所示:

ViewBag.Level = Security.GetLevel(User);

然而,一旦单元测试进入Create控制器方法,由于User对象是null,所以上面的行抛出一个NullReferenceException

关于如何为单元测试会话设置IPrincipal,有什么想法吗?

这是我现在写的测试。我试图访问User对象,并在测试进入Create方法之前简单地对其进行设置,但intellisense没有接收到它。

    [Test]
    public void a06_CloneFromDatabase()
    {
        using (AgentResources db = new AgentResources())
        {
            var master = (from a in db.AgentTransmission
                          where a.RecordStatus.Equals("C")
                          select a).FirstOrDefault();

            var result = _controlAgtTran.Create(master.ID, null, string.Empty, string.Empty, string.Empty, string.Empty, false) as ViewResult;
            var model = result.Model as AgentTransmission;
            Assert.AreEqual(model.ReferenceType, master.ReferenceType);
        }
    }

编辑

根据下面评论中提到的帖子,我找到了一种创建HttpContext会话并将IPrincipal应用于该会话的方法。在单元测试进入HttpContextIPrincipal User对象都为空的控制器之前,这种情况一直很好。

由于我使用的控制器的实例的HttpContext属性似乎是只读的(还有IPrincipalUser属性),有人知道在被测试的控制器内部通过单元测试中使用的HttpContext的方法吗?此外,如果这不可能,使用ReSharper的单元测试测试RouteValues的可用方法是什么?

    [SetUp]
    public void SetUp()
    {
        _controlAgtTran = new AgentTransmissionController();
        /****Set up Current HTTP Context to pass Security.cs checks*****/
        //Set up the HTTP Request
        var httpRequest = new HttpRequest("", "http://localhost:2574/", "");
        //Set up the HTTP Response
        var httpResponse = new HttpResponse(new StringWriter());
        //Set up the HTTP Context
        var httpContext = new HttpContext(httpRequest, httpResponse);
        var sessionContainer = new HttpSessionStateContainer("NEAROD",
                                                             new SessionStateItemCollection(),
                                                             new HttpStaticObjectsCollection(),
                                                             100,
                                                             true,
                                                             HttpCookieMode.AutoDetect,
                                                             SessionStateMode.InProc,
                                                             false);
        httpContext.Items["AspSession"] =
            typeof (HttpSessionState)
                .GetConstructor(
                    BindingFlags.NonPublic | BindingFlags.Instance,
                    null,
                    CallingConventions.Standard,
                    new[] {typeof (HttpSessionStateContainer)},
                    null)
                .Invoke(new object[] {sessionContainer});
        //Assign the context
        HttpContext.Current = httpContext;
    }
    [Test]
    public void a01_IncompleteRecordGoesToEdit()
    {
        AgentTransmission agtTran = new AgentTransmission();
        agtTran.ReferenceNumber = 95820518787;
        agtTran.ReferenceType = "S";
        agtTran.EffectiveDate = DateTime.Now;
        agtTran.RelationshipEffDate = DateTime.Now;
        agtTran.RecordStatus = "N";
        agtTran.CreatedDate = DateTime.Now;
        agtTran.CreatedOperator = "xTest1";
        agtTran.FirstName = "Unit";
        agtTran.LastName = "Test";
        agtTran.ExtRepType = "EXTREPID";
        agtTran.JIT = true;
        agtTran.SendToDRM = true;
        agtTran.SendToNMF = true;
        agtTran.WelcomeLetter = true;
        agtTran.OverrideRegionInd = false;
        //set IPrincipal 
        string[] roles = {"LCO"};
        IPrincipal principal = new GenericPrincipal(new GenericIdentity("SYMETRA\NEAROD"), roles);
        HttpContext.Current.User = principal;
        IPrincipal user = HttpContext.Current.User;
        Assert.AreEqual(user, principal); //This passes
        Assert.AreEqual(principal, _controlAgtTran.User); //this fails
        var result = (RedirectToRouteResult)_controlAgtTran.Create(agtTran); //this crashes
        //Tests aren't run
        Assert.IsNotNull(result);
        Assert.AreEqual(3, result.RouteValues.Count);
        Assert.AreEqual("AgentTransmission", result.RouteValues["controller"]);
        Assert.AreEqual("Edit", result.RouteValues["action"]);
    }

根据本文中提到的类似解决方案,我在SetUp()方法的末尾添加了以下内容。

        var controllerCtx = new ControllerContext();
        controllerCtx.HttpContext = new HttpContextWrapper(HttpContext.Current);
        _controlAgtTran.ControllerContext = controllerCtx;

将当前HttpContext封装在HttpContextBase属性(名称不恰当的controllerCtx.HttpContext)中,测试现在可以访问控制器的UserHttpContext属性。当仅使用HttpContext.Current会话时,这些属性以前是只读的,因此始终为null。

仅供参考——这是我第一次用这些对象进行单元测试,因此解释可能不到100%正确。请随时在下面发表评论,我会做出任何必要的更改。

相关内容

  • 没有找到相关文章

最新更新