在(web)应用程序中,我实现了MVP模式以分离核心问题。我的演示者使用LINQ-to-NHibernate直接查询数据库,或者有时他们在查询变得复杂时使用查询对象(但我离题了)。
我的一位演示者的简单示例如下(注意:VB.NET不是我的偏好,但是要求这样做):
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.OpenSession()
_view.DataSource = uow.Queryable(Of Campus)() _
.Cacheable() _
.AsEnumerable()
End Using
End Sub
End Class
(简化)基本演示者类如下:
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
我正在尝试使用NUnit和Rhino Mocks对我的演示者(特别是LINQ查询)进行单元测试。在上面的CampusListPresenter的单元测试用例中,我将模拟视图传递给演示者。基本上我想在这个模拟的视图对象上执行断言,以确认Datasouce属性被适当地设置。但是,这始终为空。
我的单元测试的(简化)示例如下(理解我对正确的单元测试相对较新):
<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
我实际上设置了我的单元测试以使用内存中的SQLite数据库并在setup / teardown方法中填充/销毁数据,但是上面的例子中已经省略了这一点以简化。
基本上,在这个单元测试中,我从一个模拟的会话管理器(一个用于会话管理的类 - 想想Castle.Facilities.NHibernateIntegration)返回一个真正的NHibernate ISession,这样LINQ-to-NHibernate可以/将实际返回有效的可枚举结果。无论如何在演示者实现中我分配了视图数据源(在NeedDataSource内),但是当我在这个属性上做一个断言时,指定的值总是为空。
任何人都可以帮助我吗?
亲切的问候, 莱恩。
答案 0 :(得分:1)
模拟的ICampusListView
无法保留已分配的数据源对象。以下是两种可能的解决方法。首先,您可以使用存根而不是模拟(有关模拟和存根之间差异的更多背景信息,请参阅this帖子):
_view = MockRepository.GenerateStub(Of ICampusListView)()
如果您确实想使用模拟而不是存根,请在测试中的Expect
对象上使用VerifyAllExpectations
和ICampusListView
:
'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)())