2011-01-05 94 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