您好我正在尝试在我的控制器上对我的注销操作进行单元测试,但我很难在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());
}
答案 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()
之前设定您的期望。