How to mock a method (custom behavior) with Rhino

2019-05-28 01:57发布

问题:

How can I mock one method with RhinoMocks in VB.Net? The reference I found is in C#:

 Expect.Call(delegate{list.Add(0);}).IgnoreArguments() 
     .Do((Action<int>)delegate(int item) { 
     if (item < 0) throw new ArgumentOutOfRangeException(); 
 }); 

SharpDevelop converts this to:

Expect.Call(Function() Do
            list.Add(0)
            End Function).IgnoreArguments().Do(DirectCast(Function(item As Integer) Do
                        If item < 0 Then
                            Throw New ArgumentOutOfRangeException()
                        End If
                       End Function, Action(Of Integer)))

But that doesn't work either (it doesn't compile).

This is what I want to do: create a new object and call a method which sets some properties of that method. In real-life this method, will populate the properties with values found in the database. In test, I would like to mock this method with a custom method/delegate so that I can set the properties myself (without going to the database).

In pseudo-code, this is what I'm trying to do:

 Dim _lookup As LookUp = MockRepository.GenerateMock(Of LookUp)()
 _luvalue.Expect(Function(l As LookUp) l.GetLookUpByName("test")).Do(Function(l As LookUp) l.Property = "value")

回答1:

Unfortunately you're attempting to do both a Sub lambda and a Statement Lambda. Neither are supported in VS2008 (but will be in the upcoming version of VS). Here is the expanded version that will work for VB

I'm guessing at the type of m_list

Class MockHelper
  Dim m_list as new List(Of Object)

  Public Sub New() 
    Expect(AddressOf CallHelper).IgnoreArguments().Do(AddressOf Do Hepler)
  End Sub

  Private Sub CallHelper() 
    m_list.Add(0)
  End Sub

  Private Sub DoHelper(ByVal item as Integer)
    if item < 0 Then
      Throw New ArgumentOutOfRangeException
    End If
  End Sub
End Class


回答2:

I have never mocked something w/ both a delegate and a lambda so I can't give a full solution to this problem, but I did want to share some example code for the usual "AssertWasCalled" function in Rhino Mocks 3.5 for vb developers because I spent some time trying to grok this... (keep in mind the below is kept simple for brevity)

This is the method under test - might be found inside a service class for the user object

Public Sub DeleteUserByID(ByVal id As Integer) Implements Interfaces.IUserService.DeleteUserByID
      mRepository.DeleteUserByID(id)
End Sub

This is the interactive test to assert the repository method gets called

  <TestMethod()> _
  Public Sub Should_Call_Into_Repository_For_DeleteProjectById()
    Dim Repository As IUserRepository = MockRepository.GenerateStub(Of IUserRepository)()
    Dim Service As IUserService = New UserService(Repository)

    Service.DeleteUserByID(Nothing)

    Repository.AssertWasCalled(Function(x) Wrap_DeleteUserByID(x))
  End Sub

This is the wrap function used to ensure this works w/ vb

  Function Wrap_DeleteUserByID(ByVal Repository As IUserRepository) As Object
    Repository.DeleteUserByID(Nothing)

    Return Nothing
  End Function

I found this to be a very nasty solution, but if it helps someone w/ the same issues I had it was worth the time it took to post this ;)