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
Add Word View  25 May 2019
Add Word View Model  11 May 2019
Add Word Screen  04 May 2019
WPF Projects & ViewModelBase  20 Apr 2019
Static Analysis  13 Apr 2019
Redux Store  06 Apr 2019
Commandline Builds  30 Mar 2019
Application Model  23 Mar 2019
Vocabulary Set  16 Mar 2019
Vocabulary Word  09 Mar 2019
More csharp posts »
Archives
February 2019
2019