views:

63

answers:

2

I am trying to use the AAA syntax in Rhino Mocks with VB.Net to validate that a method was called only one time. I can't seem to get it right. With this code, if the repository is called twice, it returns nothing on the second call, and the test passes. I would have expected the test to fail when VerifyAllExpectations was called.

<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
A: 

Since AssertWasCalled isn't compatible with VB i have the following (ugly) solution with demo code for you

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
slamidtfyn
+1  A: 

If you are using VS2010 you get much improved lamba support (including a much better experience using Rhino Mocks with VB)

I outline how to use AAA syntax w/ rhino mocks here (using c#) but to answer your question quickly you could do the following

First the class you want to verify some interactive behavior (super simple but it works)

Public Class Class1
    Public Overridable Sub Happy()

    End Sub

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

Next the test written using AAA + vb to prove the Happy method gets called 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
Toran Billups
Thanks Toran. I had tried this approach first, but had compiler error on the AssertWasCalled statement. I assumed I needed to call it with AssertWasCalled(function(x)... because the method I was asserting was a function. Switching it out to AssertWasCalled(Sub(x)... allows the code to work.
Paul McCann
No problem - just glad I could help. I've done a lot of testing with vb and felt like I was the only person doing so. (zero help on more complex questions like this)
Toran Billups