2

您好我正在尝试对我的控制器上的注销操作进行单元测试,但我很难在 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 时,女巫是正确的。但是我怎样才能模拟或存根已经被 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());
    }
4

1 回答 1

3

好久没用MvcContrib了,拉下最新的代码,做了个快速测试项目。这很奇怪。查看 MvcContrib 代码(特别是 TestControllerBuilder),它为大多数对象(请求、响应、服务器等)创建模拟,但不是为会话创建模拟。我不确定为什么会这样——可能要问创作者。

但是,有一种方法可以自己模拟它。您可以创建自己的模拟会话并告诉控制器使用您的模拟会话,而不是来自 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().

于 2011-01-15T19:23:23.037 回答