Mocking in Visual Basic: VB.Net and Moq

If you work with Java, you're used to using Mockito for your tests.  In VB.Net you have the free Moq product.  Unfortunately all the examples are for C#, and are pretty inscrutable.  This page exists just to show you enough syntax to do the basics.

I'm working with Visual Studio 2010 Ultimate, and the unit testing is in MSTest, although I doubt that matters.

Installing Moq

Moq is actually just a DLL.  You're supposed to install it using the Visual Studio MarketPlace, but I couldn't.  All you actually have to do is to download the .dll, put it in your solution, and then add a reference to it to your test project.  You right-click on the test project and do Add | Reference.

More detail:

Here is the download link: http://code.google.com/p/moq/downloads/detail?name=Moq.4.0.10827.Final.zip

The zip file at that location contains a .Net 4 folder:

Moq.4.0.10827.Final.zip\Moq.4.0.10827\NET40

Use the dll : Moq.dll from the NET40 folder and everthing will work fine.
Just do a normal Add Reference on the test project.

I would check the version number and the Runtime veseion of the assembly you are trying to use in My Project|properties. It should say:

Runtime Version: v4.0.20926
Version: 4.0.10827.0

Example of VB.Net using Moq

Here's a Unit test.  I've made the two classes inner classes here, but of course you would normally have them in a separate file.

The class I am testing is MyCode.  This uses another class SomeService, which we want to mock.

Option Strict On
Option Explicit On

Imports System
Imports System.Text
Imports System.Collections.Generic
Imports Microsoft.VisualStudio.TestTools.UnitTesting
Imports System.Collections
Imports System.Diagnostics
Imports Moq

<TestClass()> _
Public Class MyCodeTest

    ' Use TestInitialize to run code before running each test
    <TestInitialize()> _
    Public Sub setUp()
    End Sub

    ' Use TestCleanup to run code after each test has run
    <TestCleanup()> _
    Public Sub tearDown()
    End Sub

    '--------------------------------------------------------------------------
    '-- TESTS
    '--------------------------------------------------------------------------

    '-- Some service that we are going to mock. Class must be public in order to mock it.
    ' If you forget, you'll get "Type TestProjectQL.Bas75ApplySuffixTest+SomeServiceis not public. Can not create proxy for types that are not accessible."
    Public Class SomeService

        ' moq has to override, so the function must be marked as "Overridable". (C# = "virtual")
        Overridable Function someFunction() As String
            Return "someString"
        End Function

    End Class

    '-- Our code. Nothing special here. This is some code that calls another class that we have mocked.
    Private Class MyCodeUnderTest

        '-- Inject the service class into our code
        Function myFunction(service As SomeService) As String
            Return service.someFunction
        End Function

    End Class

    <TestMethod()> _
    Public Sub testMoqSyntax()
    Dim FunctionName As String = Reflection.MethodInfo.GetCurrentMethod.Name

        '-- Create the mock
        Dim mockService = New Mock(Of SomeService)

        '-- Configure the mock. Define a label "x" as a placeholder for the mockService class methods
        ' If you get "Invalid setup on a non-virtual (overridable in VB) member: x => x.someFunction()", 
        ' it's because you're mocking the class, not its interface. Either mark method as virtual/Overrideable, or extract interface.
        mockService.Setup(Function(x) x.someFunction).Returns("mock value")

        '-- Instantiate the code under test
        Dim myCode As New MyCodeUnderTest()

        '-- Run the code, passing the mock *object* rather than the real service
        ' If you get "Type TestProjectQL.Bas75ApplySuffixTest+SomeServiceis not public. Can not create proxy for types that are not accessible."
        ' then you need to make type public.
        Dim result As String = myCode.myFunction(mockService.Object) ' Note you must pass the .object, not the mock itself.

        '-- Check the output is the mock, not the real object
        Assert.AreEqual("mock value", result)

        '-- Verify the call to the service happened
        mockService.Verify(Function(x) x.someFunction, Moq.Times.Once)
    End Sub

End Class

Download: MyCodeTest.vb

Argument Matchers

 mockService.Setup(Function(x) x.bigFunction(It.IsAny(Of String), _
                                             It.IsAny(Of List(Of SomeClass))).Returns(New List(Of SomeResultClass))

The matchers are very much like in Mockito.  You have to use them in the Verify too, of course.  Here are some other examples in C# format.

The error messages are pretty foul, but if you google them, you can generally work out what it's complaining about.

Hope that helps!

Constructive feedback is welcomed to Roger Pearse.

Written 7th January 2022.

Return to Roger Pearse's Pages