как добавить сессию в макет httpcontext? - PullRequest
1 голос
/ 10 мая 2011

Как в примере с Скоттом Хансельманом http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx Я пытался смоделировать httpcontext, используя MockHelpers в качестве фрагмента кода ниже

controller = GetAccountController();

ActionResult result = controller.ChangePassword();

HttpContextBase hb = MvcMockHelpers.FakeHttpContext("~/Account/ChangePassword");
hb.Session.Add("id", 5);

// Assert Assert.AreEqual(5, (int)hb.Session["id"]);

Я заметил, что сеанс не был добавлен и также не получил никакой ошибки. Свойства объекта сеанса имели значение ниже

Count = 0, CodePage = 0, Content = null, IsCookieLess = null, IsNewSession = null, IsReadOnly = null, IsSynchronized = null, Keys = null, LCID = 0, Mode = off, SessionId = null, Статические объекты = null, SynRoot = null, TimeOut = 0

Я получал одинаковые результаты для насмешек Rhino и Moq.

Пожалуйста, посоветуйте мне, как добавить сеанс в макет httpcontext.

Заранее спасибо.

Ответы [ 5 ]

3 голосов
/ 10 мая 2011

Вот то, что я использую для насмешки не только сеанса, но и большинства других объектов, которые вам понадобятся (запрос, ответ и т. Д.), Этот код представляет собой коллекцию кода Стива Сандерсона и других, а также мой собственный, обратите внимание, что сеанс подделан с использованием словаря

using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web;
using System.Web.Routing;
using System.Web.Mvc;

namespace ECWeb2.UnitTests {
    public class ContextMocks {
        public Moq.Mock<HttpContextBase> HttpContext { get; private set; }
        public Moq.Mock<HttpRequestBase> Request { get; private set; }
        public Moq.Mock<HttpResponseBase> Response { get; private set; }
        public RouteData RouteData { get; private set; }
    public ContextMocks(Controller onController) {
        // Define all the common context objects, plus relationships between them
        HttpContext = new Moq.Mock<HttpContextBase>();
        Request = new Moq.Mock<HttpRequestBase>();
        Response = new Moq.Mock<HttpResponseBase>();
        HttpContext.Setup(x => x.Request).Returns(Request.Object);
        HttpContext.Setup(x => x.Response).Returns(Response.Object);
        HttpContext.Setup(x => x.Session).Returns(new FakeSessionState());
        Request.Setup(x => x.Cookies).Returns(new HttpCookieCollection());
        Response.Setup(x => x.Cookies).Returns(new HttpCookieCollection());
        Request.Setup(x => x.QueryString).Returns(new NameValueCollection());
        Request.Setup(x => x.Form).Returns(new NameValueCollection());

        // Apply the mock context to the supplied controller instance
        RequestContext rc = new RequestContext(HttpContext.Object, new RouteData());
        onController.ControllerContext = new ControllerContext(rc, onController);
        onController.Url = new UrlHelper(rc);
    }

    ContextMocks() {
    }

    // Use a fake HttpSessionStateBase, because it's hard to mock it with Moq
    private class FakeSessionState : HttpSessionStateBase {
        Dictionary<string, object> items = new Dictionary<string, object>();
        public override object this[string name] {
            get { return items.ContainsKey(name) ? items[name] : null; }
            set { items[name] = value; }
        }
    }
}

}

2 голосов
/ 10 мая 2011

Код, на который вы ссылались, объясняет, как вы можете подделать httpcontext - он на самом деле ничего не делает, когда вы вызываете "hb.Session.Add" - он просто предотвращает сбой теста из-за зависимости от HttpContext.

1 голос
/ 19 июля 2012

Это то, что я обычно делаю

//Mock The Sesssion
_session = MockRepository.GenerateStrictMock<httpsessionstatebase>();
_session.Stub(s => s["Connectionstring"]).Return(Connectionstring);

//Mock The Context 
_context = MockRepository.GenerateStrictMock<httpcontextbase>();
_context.Stub(c => c.Session).Return(_session);

var databaseExplorerController = new DatabaseExplorerController(repository);

//Assign COntext to controller
databaseExplorerController.ControllerContext = new ControllerContext(_context, new RouteData(),
                                                                     _databaseExplorer);

Я написал небольшую статью об этом на

http://www.gigawebsolution.com/Posts/Details/66/Mock-Session-in-MVC3-using-Rhino-Mock

Надеюсь, это поможет

1 голос
/ 14 августа 2011

Вы можете использовать библиотеку MVC Contrib, предоставленную Outercurve Foundation, для макетирования состояния сеанса и других объектов, доступных во время обработки обычного запроса (HttpRequest, HttpResponse ... и т. Д.).

http://mvccontrib.codeplex.com/ (или используйте NuGet для его загрузки)

Содержит библиотеку TestHelper , которая помогает быстро создавать модульные тесты.

Например:

[TestMethod]
public void TestSomething()
{
    TestControllerBuilder builder = new TestControllerBuilder();

    // Arrange
    HomeController controller = new HomeController();

    builder.InitializeController(controller);

    // Act
    ViewResult result = controller.About() as ViewResult;

    // Assert
    Assert.IsNotNull(result);
}

Используя тип TestControllerBuilder, предоставляемый библиотекой MVC Contrib TestHelper, вы можете быстро инициализировать свой контроллер и инициализировать его внутренние элементы данных (HttpContext, HttpSession, TempData ...).

Конечно, сам HttpSessionState также подвергается насмешкам, поэтому добавление чего-либо к нему (Session.Add) на самом деле ничего не даст. Как и предполагалось, мы это высмеяли.

Похоже, что вы хотите смоделировать HttpContext, но все равно настроить его с рабочим состоянием сеанса. Похоже, вы хотите сделать что-то, как описано здесь:

http://jasonbock.net/jb/Default.aspx?blog=entry.161daabc728842aca6f329d87c81cfcb

0 голосов
/ 17 мая 2013

Немного поздно, но это то, что используется.

Я использую инфраструктуру MoQ из https://code.google.com/p/moq/

Теперь сеанс можно использовать в реализации контроллера.

    private class MockHttpSession : HttpSessionStateBase
    {
        readonly Dictionary<string, object> _sessionDictionary = new Dictionary<string, object>();
        public override object this[string name]
        {
            get
            {
                object obj = null;
                _sessionDictionary.TryGetValue(name, out obj);
                return obj;
            }
            set { _sessionDictionary[name] = value; }
        }
    }

    private ControllerContext CreateMockedControllerContext()
    {
        var session = new MockHttpSession();
        var controllerContext = new Mock<ControllerContext>();
        controllerContext.Setup(m => m.HttpContext.Session).Returns(session);

        return controllerContext.Object;
    }

    [TestMethod]
    public void Index()
    {
        // Arrange
        MyController controller = new MyController();
        controller.ControllerContext = CreateMockedControllerContext(); 

        // Act
        ViewResult result = controller.Index() as ViewResult;

        ....
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...