已使用 Rhino.Mocks 正确分配模拟对象的断言属性

发布于 2024-12-07 01:39:38 字数 2808 浏览 0 评论 0原文

在(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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

森罗 2024-12-14 01:39:38

模拟的 ICampusListView 无法保留分配的数据源对象。这里有两种可能的方法来解决这个问题。首先,您可以使用存根而不是模拟(有关模拟和存根之间差异的更多背​​景信息,请参阅 this post):

_view = MockRepository.GenerateStub(Of ICampusListView)()

如果您确实想使用模拟而不是存根,请使用 Expect 和测试中 ICampusListView 对象上的 VerifyAllExpectations

    '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)())

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)())
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文