VBMock: A Beginner’s Guide to Mocking in Visual Basic
Unit testing is essential for producing reliable, maintainable code. When testing components that depend on external services or complex collaborators, mocks let you isolate the unit under test and control its environment. VBMock is a lightweight mocking framework for Visual Basic that simplifies creating, configuring, and verifying mock objects. This guide introduces core concepts and practical examples so you can start using VBMock quickly.
What is VBMock?
VBMock provides an API to create fake implementations (mocks) of interfaces and classes used by your code. Instead of instantiating real dependencies in tests, you create mocks that:
- Return controlled values
- Record calls for later verification
- Throw exceptions to simulate error paths
Using mocks makes tests deterministic and fast, and helps you focus on the behavior of the unit under test.
When to use mocks
Use mocks when:
- A dependency is slow, non-deterministic, or has side effects (database, web service, file system).
- You want to isolate logic under test from collaborators.
- You need to assert that interactions with a dependency occurred (calls, arguments, call counts). Avoid over-mocking simple value objects or when an in-memory/fake implementation is easier to maintain.
Installing VBMock
Install VBMock via NuGet in your Visual Studio test project:
Ensure your test project targets a compatible .NET Framework or .NET version supported by VBMock.
Core concepts
- Mock object: the fake instance that replaces a real dependency.
- Arrange: configure the mock behavior or return values.
- Act: execute the code under test.
- Assert: verify results and interactions with the mock.
VBMock supports setting up return values, recording calls, and verifying calls with argument matching.
Basic example
Assume an interface and a class under test:
Public Interface IEmailService Sub SendEmail(toAddress As String, subject As String, body As String) End Interface
Public Class OrderProcessor
Private ReadOnly _emailService As IEmailService Public Sub New(emailService As IEmailService) _emailService = emailService End Sub Public Sub ProcessOrder(orderId As Integer) ' order processing logic... _emailService.SendEmail("[email protected]", "Order processed", $"Order {orderId} processed") End Sub
End Class
A unit test with VBMock:
Public Class OrderProcessorTests
<TestMethod> Public Sub ProcessOrder_SendsNotification() ' Arrange Dim mock As New VBMock.Mock(Of IEmailService)() Dim processor As New OrderProcessor(mock.Object) ' Act processor.ProcessOrder(42) ' Assert mock.Verify(Sub(m) m.SendEmail("[email protected]", "Order processed", "Order 42 processed"), Times.Once()) End Sub
End Class
This test verifies that SendEmail was called once with the expected arguments.
Setting return values
For methods that return values, configure the mock like this:
Public Interface IProductRepository Function GetStock(productId As Integer) As Integer End Interface
’ Test Dim mockRepo As New VBMock.Mock(Of IProductRepository)() mockRepo.Setup(Function(m) m.GetStock(10)).Returns(5)
Dim stock = mockRepo.Object.GetStock(10) Assert.AreEqual(5, stock)
VBMock’s Setup and Returns let you control return values based on arguments.
Argument matching and flexible verification
Use argument matchers when exact values aren’t known or when you want general checks:
mock.Verify(Sub(m) m.SendEmail(It.IsAny(Of String)(), “Order processed”, It.IsStringContaining(“Order”)), Times.Once())
Common matchers: It.IsAny(Of T)(), It.Is(Of T)(Function(x) …), and helper matchers for strings or ranges.
Simulating exceptions
To test error handling, configure a mock to throw:
mockRepo.Setup(Function(m) m.GetStock(999)).Throws(New InvalidOperationException(“DB error”))
Then assert your code responds appropriately when that exception occurs.
Verifying call counts and order
VBMock supports verifying how many times a method was called (Times.Once, Times.Never, Times.AtLeastOnce, etc.). For complex scenarios, you can also verify call order using sequences or manual recording.
Best practices
- Prefer testing behavior (interactions) when dependencies are external; prefer state assertions when possible.
- Keep mock setups focused on the unit under test; avoid mirroring complex production logic inside tests.
- Use descriptive test names indicating the expected behavior.
- Reset or recreate mocks between tests to avoid cross-test interference.
- Don’t mock the system under test itself; mock its dependencies.
Troubleshooting
- If Setup doesn’t match at runtime, ensure argument values/matchers match exactly or use It.Is matchers.
- If tests are brittle, consider simpler fakes or test helpers instead of heavy mocking.
- Confirm the mocked types are interfaces or virtual/overridable methods on classes (depending on VBMock capabilities).
Summary
VBMock makes it straightforward to isolate and test Visual Basic code by creating controllable mock objects. With key operations—setup, return configuration, exception simulation, and verification—you can write fast, reliable unit tests that assert both outcomes and interactions. Start by mocking core external dependencies and expand coverage gradually while keeping tests maintainable.
If you want, I can convert one of your existing tests to use VBMock or provide examples for asynchronous methods, events, or property setups.