已使用 Rhino.Mocks 正确分配模拟对象的断言属性
在(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
我正在尝试对我的演示者进行单元测试(特别是 LINQ 查询)使用 NUnit 和 Rhino Mocks。在上述 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 数据库并在设置/拆卸方法中填充/销毁数据,但为了简单起见,上面的示例已将其全部省略。
基本上,在这个单元测试中,我从模拟的会话管理器(用于会话管理的类 - 想想 Castle.Facilities.NHibernateIntegration)返回一个真正的 NHibernate ISession,以便 LINQ-to-NHibernate 可以/将实际返回有效的可枚举结果。无论如何,在演示者实现中,我分配了视图数据源(在 NeedDataSource 内),但是当我对此属性进行断言时,分配的值始终为 null。
有人可以帮我吗?
亲切的问候, 瑞安.
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.OpenSession()
_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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
模拟的
ICampusListView
无法保留分配的数据源对象。这里有两种可能的方法来解决这个问题。首先,您可以使用存根而不是模拟(有关模拟和存根之间差异的更多背景信息,请参阅 this post):如果您确实想使用模拟而不是存根,请使用
Expect
和测试中ICampusListView
对象上的VerifyAllExpectations
: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):If you do want to use mocks instead of stubs, use
Expect
andVerifyAllExpectations
on theICampusListView
object in your test: