When unit testing, it is common to create a fake implementation of an interface so that you can test another component in isolation. But how do you handle the case where each test needs a fake that does something different?

Here’s an approach that I’ve found quite useful - a fake implementation that allows you to plug in the behaviour needed for the test at hand.

Consider a simple interface for sending messages:

public interface IMessageDispatcher<T>
{
    void SendMessage(T message);
    void PostMessage(T message);
}

Using explicit implementation of the interface, we can create a fake that makes it really easy for consumers to provide their own functionality:

public class FakeMessageDispatcher<T> : IMessageDispatcher<T>
{
    public Action<T> SendMessage { get; set; }
    public Action<T> PostMessage { get; set; }

    void IMessageDispatcher<T>.SendMessage(T message)
        => SendMessage?.Invoke(message);

    void IMessageDispatcher<T>.PostMessage(T message)
        => PostMessage?.Invoke(message);
}

This fake acts as a null implementation if not configured; the writable properties SendMessage and PostMessage allow consumers to provide their own implementation.

For example, here’s a simple test class demonstration.

public class MessengerTests
{
    private readonly FakeMessageDispatcher<string> _dispatcher;
    private readonly Store _store;

    public MessengerTests()
    {
        _dispatcher = new FakeMessageDispatcher<string>();
        _store = new Store(_dispatcher);
    }

    [Fact]
    public void Purchase_GivenProduct_SendsMessage()
    {
        string message = null;
        _dispatcher.SendMessage = m => message = m;

        _store.Purchase("socks");

        message.Should().NotBeNull();
    }
}

Comments

blog comments powered by Disqus
Next Post
Converting a List to a Queue  23 Feb 2019
Prior Post
Capturing Transient Errors  09 Feb 2019
Related Posts
Caching without Race Conditions  13 Jun 2020
Improved Caching  09 May 2020
Caching Speech  25 Apr 2020
Speech Middleware  11 Apr 2020
Redux Middleware Implementation  28 Mar 2020
Redux Middleware  14 Mar 2020
Always review code you copy  29 Feb 2020
Speech API  15 Feb 2020
Logging Implementation  25 Jan 2020
Logging Demonstrated  11 Jan 2020
More csharp posts »
Archives
February 2019
2019