Mocking is an important aspect of writing unit tests. The current project that I am on does a lot of integration testing, but not much unit testing. I'm trying to increase the amount of true unit tests, but struggle to do so due to the difficulty in mocking subroutines.
The team that I am on had selected Moq as the mocking framework of choice prior to my arrival, however there aren't actually any tests using it. As long as I am mocking functions on an interface, Moq is an acceptable framework, however subroutines are completely unmockable. I have done a fair amount of googling, and there seems to be quite a few questions on Stackoverflow about it, but no real answers.
In this particular case, what I want to do with mocking is ensure that the proper subroutine is called when I pass in an object that matches certain criteria. I am able to get it to work with Rhino Mocks by doing the following:
_
Public Sub SaveProposal_WhenProposalIsNew_CallCreate()
Dim proposal = New Proposal("title", "description")
Dim dataProvider = MockRepository.GenerateMock(Of IProposalDataProvider)()
dataProvider.Expect(Function(dp) CreateProposal(dp)).IgnoreArguments()
Dim service = New ProposalService(dataProvider, TestAppContext.Current)
service.SaveProposal(proposal)
dataProvider.VerifyAllExpectations()
End Sub
Private Function CreateProposal(ByVal dp As IProposalDataProvider)
dp.CreateProposal(Nothing)
Return Nothing
End Function
However, when I try something similar with Moq using the code below:
_
Public Sub SaveProposal_WhenProposalIsNew_CallCreate()
Dim proposal = New Proposal("title", "description")
Dim dataProvider = New Mock(Of IProposalDataProvider)()
dataProvider.Setup(Function(dp As IProposalDataProvider) CreateProposal(dp))
Dim service = New ProposalService(dataProvider.Object, TestAppContext.Current)
service.SaveProposal(proposal)
dataProvider.VerifyAll()
End Sub
Private Function CreateProposal(ByVal dp As IProposalDataProvider)
dp.CreateProposal(It.IsAny(Of ProposalDto))
Return Nothing
End Function
I get the following exception:
System.ArgumentException: Invalid setup on a non-overridable member: dp => value(ProposalManagerApp.Tests.ProposalServiceTests).CreateProposal(dp).
Any mock-magicians out there know the answer? The problem stems from the inability of VB to create an Expression(Of Action(Of Something)) because lambdas must return a value. The universe plans on correcting itself with the release of VB10, by allowing Sub() lambdas, but I can't wait that long.