MVCContrib TestHelper проблема с session.clear, session.abandon и Rhino Mock - PullRequest
2 голосов
/ 06 января 2011

Привет! Я пытаюсь выполнить модульное тестирование своего действия по выходу из системы на моем контроллере, но у меня трудные времена для проверки или заглушки моего сеанса в HttpContext. Я использую MVC Contrib TestHelper , чтобы сделать это проще, но теперь мне нужна небольшая помощь.

Вот мой тест:

[TestFixture]
    public class SessionControllerTest
    {
        private ISession _session;
        private IConfigHelper _configHelper;
        private IAuthenticationService _authService;
        //private IMailHelper _mailHelper;
        private ICryptographer _crypto;
        private SessionController _controller;
        private TestControllerBuilder _builder;
        private MockRepository _mock;
    [SetUp]
    public void Setup()
    {
        _mock = new MockRepository();
        _session = _mock.DynamicMock<ISession>();
        _configHelper = _mock.DynamicMock<IConfigHelper>();
        _authService = _mock.DynamicMock<IAuthenticationService>();
        //_mailHelper = _mock.DynamicMock<IMailHelper>();
        _crypto = _mock.DynamicMock<ICryptographer>();
        _controller = new SessionController(_authService, _session, _crypto, _configHelper);
        _builder = new TestControllerBuilder();
        _builder.InitializeController(_controller);
    }
[Test]
        public void Logout_ReturnRedirectToAction()
        {
        _builder.InitializeController(_controller);

        _authService.SignOut();
        LastCall.Repeat.Once();
        _builder.Session["memberNumber"] = string.Empty;
        LastCall.Repeat.Once();
        _controller.Session.Clear();
        LastCall.Repeat.Any();
        _controller.Session.Abandon();
        LastCall.Repeat.Any();
        //_builder.Session.Stub(s => s.Clear());
        //_builder.Session.Stub(s => s.Abandon());
        //_builder.Session.Clear();
        //LastCall.Repeat.Once();
        //_builder.Session.Abandon();
        //LastCall.Repeat.Once();

        _mock.ReplayAll();
        var result = _controller.Logout();

        _mock.VerifyAll();
        result.AssertActionRedirect().ToAction<SessionController>(c => c.Login());
    }

Вы можете увидеть мои попытки по-разному. Я получаю сообщение об ошибке, сообщающее, что Session.Abandon () не реализован, ведь вы правы, если взглянуть на TestHelper в MVCContrib. Но как я могу издеваться или заглушить сеанс, который уже высмеян TestHelper?

Исключение в NUnit:

System.NotImplementedException: метод или операция не реализованы. в MvcContrib.TestHelper.MockSession.Abandon ()

Спасибо за помощь!

РЕДАКТИРОВАТЬ: вот новый рабочий тест

[Test]
    public void Logout_ReturnRedirectToAction()
    {
        _builder.InitializeController(_controller);
        var mockSession = _mock.Stub<HttpSessionStateBase>();

        _controller.HttpContext.BackToRecord();
        _controller.HttpContext.Stub(c => c.Session).Return(mockSession);
        _controller.HttpContext.Replay();

        _authService.SignOut();
        LastCall.Repeat.Once();
        _builder.Session["memberNumber"] = string.Empty;
        _controller.Session.Clear();
        LastCall.Repeat.Once();
        _controller.Session.Abandon();
        LastCall.Repeat.Once();

        _mock.ReplayAll();
        var result = _controller.Logout();

        _mock.VerifyAll();
        result.AssertActionRedirect().ToAction<SessionController>(c => c.Login());
    }

1 Ответ

3 голосов
/ 15 января 2011

Прошло много времени с тех пор, как я использовал MvcContrib, поэтому я собрал последний код и сделал быстрый тестовый проект.Это очень странно.Глядя на код MvcContrib (в частности, TestControllerBuilder), он создает макеты для большинства объектов (запрос, ответ, сервер и т. Д.), Но не для Session.Я не уверен, почему это так - возможно, придется спросить создателей.

Однако, есть способ издеваться над этим самостоятельно.Вы можете создать свой собственный фиктивный сеанс и указать контроллеру использовать свой вместо сеанса из MvcContrib.TestHelpers.Вот что я сделал в своем тесте:

var mockSession = MockRepository.GenerateStub<HttpSessionStateBase>();
controller.HttpContext.BackToRecord();
controller.HttpContext.Stub(c => c.Session).Return(mockSession);
controller.HttpContext.Replay();

Теперь я запускаю свой метод контроллера и затем использую синтаксис AAA Rhino.Mocks, чтобы убедиться, что метод Abandon был вызван:

controller.Session.AssertWasCalled(s => s.Abandon());

Если вы хотите использовать семантику записи / воспроизведения, вы можете установить свои ожидания перед вызовом controller.HttpContext.Replay().

...