【问题标题】:Rhino Mocks: How to verify a method was called exactly once using vb.net and AAA syntaxRhino Mocks:如何使用 vb.net 和 AAA 语法验证方法被调用一次
【发布时间】:2010-09-26 15:09:26
【问题描述】:

我正在尝试在带有 VB.Net 的 Rhino Mocks 中使用 AAA 语法来验证一个方法是否只被调用了一次。我似乎无法正确处理。使用此代码,如果存储库被调用两次,则在第二次调用时它不返回任何内容,并且测试通过。当调用 VerifyAllExpectations 时,我预计测试会失败。

<TestMethod()>
Public Sub GetDataCallsRepositoryOneTime()
    Dim repository As IDataRepository = MockRepository.GenerateMock(Of IDataRepository)()
    Dim cacheRepository As New CachingDataRepository(repository)
    Dim results1 As IEnumerable(Of DataItem)
    Dim results2 As IEnumerable(Of DataItem)

    'verify that the base repository was asked for its data one time only
    repository.Expect(Function(x) x.GetData(1)).Return(GetSampleData).Repeat.Once()

    results1 = cacheRepository.GetData(1)
    results2 = cacheRepository.GetData(1)

    sdr.VerifyAllExpectations()
End Sub

【问题讨论】:

  • 你是用vb的VS2008还是VS2010?
  • 我正在使用 Visual Studio 2010,针对我的测试项目的 4.0 框架,并针对我正在测试的项目的 3.5 框架。

标签: vb.net unit-testing rhino-mocks


【解决方案1】:

如果您使用的是 VS2010,您会得到 much improved lamba support(包括在 VB 中使用 Rhino Mocks 的更好体验)

我概述了如何使用带有 rhino mocks here(使用 c#)的 AAA 语法,但要快速回答您的问题,您可以执行以下操作

首先你要验证一些交互行为的类(超级简单但有效)

Public Class Class1
    Public Overridable Sub Happy()

    End Sub

    Public Overridable Sub DoIt()
        Me.Happy()
        Me.Happy()
    End Sub
End Class

接下来使用 AAA + vb 编写的测试来证明 Happy 方法被调用 2x

<TestClass()>
Public Class UnitTest2

    <TestMethod()>
    Public Sub TestMethod1()
        Dim x = MockRepository.GeneratePartialMock(Of Class1)()

        x.DoIt()

        x.AssertWasCalled(Sub(y) y.Happy(), Sub(z) z.Repeat.Times(2))
    End Sub

End Class

【讨论】:

  • 感谢托兰。我首先尝试过这种方法,但 AssertWasCalled 语句出现编译器错误。我假设我需要用 AssertWasCalled(function(x)... 调用它,因为我断言的方法是一个函数。将它切换到 AssertWasCalled(Sub(x)... 允许代码工作。
  • 没问题 - 很高兴我能提供帮助。我用 vb 做了很多测试,感觉我是唯一这样做的人。 (对此类更复杂的问题零帮助)
【解决方案2】:

由于 AssertWasCalled 与 VB 不兼容,我为您提供了以下(丑陋的)解决方案和演示代码

Public Interface datarepository
    Function GetData(ByVal id As Integer) As IEnumerable(Of String)
End Interface

Public Class cacherepository
    Dim _datarepository As datarepository
    Dim results As New Dictionary(Of Integer, IEnumerable(Of String))

    Public Sub New(ByVal datarepository As datarepository)
        _datarepository = Datarepository
    End Sub

    Public Function GetData(ByVal id As Integer) As IEnumerable(Of String)
        Dim result As New List(Of String)
        If results.TryGetValue(id, result) = False Then
            result = _datarepository.GetData(id)
            'Uncomment the following line to make the test pass'
            'results.Add(id, result)'
        End If
        GetData = result
    End Function
End Class

<TestClass()>
Public Class UnitTest1

    <TestMethod()>
    Public Sub TestMethod1()
        Dim datarep As datarepository = MockRepository.GenerateMock(Of datarepository)()
        Dim cacherep = New cacherepository(datarep)
        cacherep.GetData(1)
        datarep.Expect(Function(x) x.GetData(1)).Throw(New ApplicationException("FAILED TEST"))
        Try
            cacherep.GetData(1)
        Catch ex As ApplicationException
            Assert.Fail("GetData is called more than once")
        End Try
    End Sub

End Class

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-20
    • 2012-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多