2011-01-05 91 views
2

嗨我想单元测试我的控制器注销行动,但我有困难的时候测试或存根在HttpContext我的会话。我使用MVC Contrib TestHelper使它更容易,但现在我需要一点帮助。MVCContrib TestHelper问题与session.clear,session.abandon和犀牛模拟

这里是我的测试:

[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()); 
    } 

你可以看到我型动物attemps。我得到一个错误,告诉我Session.Abandon()没有实现,当你看MVCContrib的TestHelper时,女巫是正确的。但是,我怎样才能模拟或者存储已经被TestHelper嘲笑的Session呢?

在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()); 
    } 

回答

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()之前设置您的期望值。

+0

谢谢帕特里克,它工作的很棒!我不知道BackToRecord()。 – VinnyG 2011-01-17 14:58:14