Обновление: передача HttpContext и IPrincipal в Controler в модульном тесте ReSharper

Я пытаюсь запустить пару базовых модульных тестов на контроллере ASP MVC, однако в какой-то момент контроллер должен проверить IPrincipalUser объект вроде так:

ViewBag.Level = Security.GetLevel(User);

Как только тестовый модуль входит в Create Метод контроллера, однако, приведенная выше строка бросает NullReferenceException как User объект null,

Любые идеи о том, как установить 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 на эту сессию. Это работает нормально, пока тестовый модуль не переместится в контроллер, где HttpContext а также IPrincipalUser все объекты, опять же, нулевые.

Так как кажется, что экземпляр контроллера, который я использую, имеет HttpContext свойство только для чтения (и IPrincipalUser собственность) знает ли кто-нибудь способ прохождения HttpContext используется в модульном тестировании внутри тестируемого контроллера? Кроме того, если это невозможно, какой метод тестирования можно использовать? 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"]);
    }

1 ответ

Решение

Следуя аналогичному решению, упомянутому в этом посте, я добавил следующее в конец SetUp() метод.

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

Обтекание тока HttpContext внутри HttpContextBase собственность (неправильно названная controllerCtx.HttpContext) тест теперь имеет доступ к User а также HttpContext свойства контроллера. Эти свойства ранее были доступны только для чтения при использовании только HttpContext.Current сеанс и, следовательно, всегда ноль.

К вашему сведению - это мое первое модульное тестирование с этими объектами, поэтому объяснение может быть менее чем на 100% правильным. Пожалуйста, не стесняйтесь комментировать ниже, и я сделаю все необходимые изменения.

Другие вопросы по тегам