In a (web) application I've implemented the MVP pattern for seperation of core concerns. My presenters directly query the database using LINQ-to-NHibernate, or sometimes they use query objects when the query becomes complex (but I digress).
An simple example of one of my presenters is as follows (note: VB.NET is not my preference, but a requirement for this):
Public Class CampusListPresenter
Inherits BasePresenter(Of ICampusListView)
Public Sub New(ByVal view As ICampusListView)
MyBase.New(view)
End Sub
Public Sub NeedDataSource()
Using uow As ISession = _sessionManager.O开发者_运维问答penSession()
_view.DataSource = uow.Queryable(Of Campus)() _
.Cacheable() _
.AsEnumerable()
End Using
End Sub
End Class
The (simplified) base presenter class is as follows:
Public MustInherit Class BasePresenter(Of TView)
Protected _view As TView
Protected _sessionManager As ISessionManager
Public Sub New(ByVal view As TView)
Guard.Against(view Is Nothing, "view cannot be null.")
_view = view
End Sub
Public WriteOnly Property SessionManager As ISessionManager
Set(ByVal value As ISessionManager)
_sessionManager = value
End Set
End Property
End Class
I'm trying to unit test my presenters (specifically the LINQ queries) using NUnit and Rhino Mocks. In my unit test case for the above CampusListPresenter, I pass a mocked view to the presenter. Essentially I want perform an assertion on this mocked view object to confirm the Datasouce property gets set appropriately. However, this is always null.
A (simplified) example of my unit test is as follows (understand I'm relatively new to proper unit testing):
<TestFixture()> _
Public Class CampusListPresenterTests
Dim _realSessionManager As ISessionManager
<TestFixtureSetUp()> _
Public Sub TestFixtureSetUp()
_realSessionManager = DefaultSessionManager.Instance
End Sub
Dim _view As ICampusListView
Dim _fakeSessionManager As ISessionManager
<SetUp()> _
Public Sub Setup()
_view = MockRepository.GenerateMock(Of ICampusListView)()
_fakeSessionManager = MockRepository.GenerateMock(Of ISessionManager)()
End Sub
<Test()> _
Public Sub NeedDataSource_UsingRealSession_DataSourceIsAssigned()
'Arrange
Dim realSession As ISession = _realSessionManager.OpenSession()
_fakeSessionManager.Expect(Function(sm) sm.OpenSession()).Return(realSession)
'Act
Dim presenter As New CampusListPresenter(_view)
presenter.SessionManager = _fakeSessionManager
presenter.NeedDataSource()
'Assert
_fakeSessionManager.VerifyAllExpectations()
Assert.AreEqual(_view.DataSource, realSession.Queryable(Of Campus)())
End Sub
End Class
I actually setup my unit tests to use an in memory SQLite database and populate/destroy data in the setup/teardown methods, but this has all been omitted from the above example for simplicty.
Basically, in this unit test I'm returning a real NHibernate ISession from a mocked session manager (a class used for session management - think Castle.Facilities.NHibernateIntegration) so that the LINQ-to-NHibernate can/will actually return valid enumerable results. Anyway in the presenter implementation I assign the views datasource (inside NeedDataSource), but when I do an assertion on this property the assigned value is always null.
Can anyone help me out?
Kind regards, Ryan.
The mocked ICampusListView
is unable to keep hold of the assigned datasource object. Here are two possible ways to fix this. First, you could use a stub instead of a mock (for more background info on the difference between mocks and stubs, see this post):
_view = MockRepository.GenerateStub(Of ICampusListView)()
If you do want to use mocks instead of stubs, use Expect
and VerifyAllExpectations
on the ICampusListView
object in your test:
'Arrange
Dim realSession As ISession = _realSessionManager.OpenSession()
_fakeSessionManager.Expect(Function(sm) sm.OpenSession()).Return(realSession)
_view.Expect(Function(v) v.SetDataSource(Arg(Of DataSource).Is.Anything))
'Act
Dim presenter As New CampusListPresenter(_view)
presenter.SessionManager = _fakeSessionManager
presenter.NeedDataSource()
'Assert
_fakeSessionManager.VerifyAllExpectations()
_view.VerifyAllExpectations()
Assert.AreEqual(_view.DataSource, realSession.Queryable(Of Campus)())
精彩评论