Re-usable mocks in .NET using Moq
Tags: dotnet, testing
Published: 2024-03-03 09:13:03

---
title: Re-usable mocks in .NET using Moq
published: true
date: 2023-08-04 22:53:00 UTC
tags: dotnet,testing
canonical_url: https://jason.sultana.net.au/dotnet/testing/2023/08/05/strongly-typed-mocks.html
---

G’day guys!

A while back I wrote a little example of [using the Builder pattern in automated tests](/dotnet/testing/2021/07/31/using-the-builder-pattern-to-help-your-unit-tests.html), and I wanted to follow it up with another common practice that I employ in test projects - re-usable mocks.

![](https://jason.sultana.net.au/static/img/mocking-me.gif)

# What are mocks again?

For those of you who might be new-ish to automated tests, imagine you’ve got a class that looks something like this:

```
public class Mailer
{
    private readonly ISmtpClient _smtpClient;

    public Mailer(ISmtpClient smtpClient)
    {
        _smtpClient = smtpClient;
    }

    public async Task SendMailAsync(SendMailRequest request)
    {
        await _smtpClient.SendAsync(new SmtpMessage()
        {
            Port = 25,
            To = request.To,
            Credentials = CredentialsFactory.GetSmtpCredentials(),
            // ...
        });
    }
}

```

<sub>Note: The above code is an imaginary sample. These classes don’t actually exist.</sub>

If we wanted to create an isolated test for this, that doesn’t actually send any emails (i.e - a unit test) then we need a way of creating a fake instance of `ISmtpClient` that we control, which doesn’t actually send any mail, but allows us to inspect when methods get called, provide dummy data, etc. That’s basically a mock.

# Writing mocks with…Moq

If we then wanted to create a unit test (with mocks) for the above mailer class, it might looks something like this:

```
public class MailerTests
{
    [Fact]
    public async Task Can_send_mail()
    {
        // Arrange
        var smtp = new Mock<ISmtpClient>();
        smtp.Setup(m => m.SendAsync(It.IsAny<SmtpRequest>())).Verifiable();

        // Act
        var sut = new Mailer(smtp.Object);
        await sut.SendMailAsync(new SendMailRequest()
        {
            // 
        });

        // Assert
        smtp.Verify(); // this will throw if SendAsync was not called
    }
}

```

In short, we create a mock of `ISmtpClient` called `smtp`, set it up so that it mocks the `SendAsync` method and mark it as verifiable - so that we can _verify_ if it was called later. We pass the mock into the `Mailer` (the service under test) and then verify later that the method was called.

# Sounds good! What’s wrong with this?

I wouldn’t say that anything is _wrong_ with it - but it can be made more reusable. Let’s just say that we had a couple of other tests (and potentially other services, which all have their own tests, too) that all use the `ISmtpClient`. We’d have to repeat this process of creating a mock every time. Whereas instead, we could do this:

```
public class MockSmtpClient : IMock<SmtpClient>
{
    public MockSmtpClient SetupSendAsync(bool veriable = false)
    {
        var setup = Setup(m => m.SendAsync(It.IsAny<SmtpRequest>()));

        if (verifiable)
            setup.Verifiable();

        return this;
    }
}

```

The idea is that now we have a _re-usable_ mock that we can use across multiple tests. Especially when the service that you’re mocking contains a number of methods that will be used (think repositories and other data-related services), this can make the test code a lot more concise and readable. It also means that if you ever want to change how all your mocks are setup (eg: to make them all verifable), you should have far fewer places to change than trying to change every instance of `Mock<T>`.

Anyway - that about wraps me up. Does anyone follow a similar practice, or have any other common practices when it comes to automated tests? Let me know in the comments!

Catch ya!