MVCContrib TestHelper与session.clear,session.abandon和Rhino Mock有关

时间:2011-01-05 22:03:16

标签: asp.net-mvc-2 nunit rhino-mocks mvccontrib-testhelper

您好我正在尝试在我的控制器上对我的注销操作进行单元测试,但我很难在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()没有实现,当你看一下MVCContrib的TestHelper时,这是正确的。但是我如何模拟或Stub已经被TestHelper嘲笑的Session?

NUnit中的例外:

  

System.NotImplementedException:The   方法或操作不是   实现。在   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 个答案:

答案 0 :(得分:3)

我使用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();

现在我运行我的控制器方法,然后使用Rhino.Mocks的AAA语法来确保调用Abandon方法:

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

如果您想使用记录/重播语义,可以在致电controller.HttpContext.Replay()之前设定您的期望。