A brief post to show how to create an extension method that quickly and simply mocks out the fluent methods of an interface.

First though we need to define what a fluent interface is: Put simply a fluent interface (or api) is one that allows you to chain method calls. This 2012 article by Eric Vogel has a nice simple demonstration.

So let’s imagine that we are going to use the two interfaces defined in that article in our code. The interfaces look like this:

public interface IFluentEmailSender
{
    IFluentEmailSender FromServer(string host);
    IFluentEmailSender WithCredentials(string username, string password);
    IFluentEmailMessage CreateEmail();
    void Send();
}
public interface IFluentEmailMessage
{
    IFluentEmailMessage From(string fromAddress);
    IFluentEmailMessage To(string toAddress);
    IFluentEmailMessage Saying(string message);
    IFluentEmailMessage WithSubject(string subject);
    IFluentEmailSender Done();
}

We need to write some code to consume these interfaces, and because we’re good developers, we’re going to do this with TDD and write some tests. What you’ll quickly find is that somewhere in your code you have code that looks similar to the following…

[SetUp]
public void SetUp()
{
    var messageMock = new Mock<IFluentEmailMessage>();
    var senderMock = new Mock<IFluentEmailSender>();

    messageMock.Setup(m => m.From(It.IsAny<string>())).Returns(messageMock.Object);
    messageMock.Setup(m => m.To(It.IsAny<string>())).Returns(messageMock.Object);
    messageMock.Setup(m => m.Saying(It.IsAny<string>())).Returns(messageMock.Object);
    messageMock.Setup(m => m.WithSubject(It.IsAny<string>())).Returns(messageMock.Object);
    messageMock.Setup(m => m.Done()).Returns(senderMock.Object);

    senderMock.Setup(s => s.FromServer(It.IsAny<string>())).Returns(senderMock.Object);
    senderMock.Setup(s => s.WithCredentials(It.IsAny<string>(), It.IsAny<string>())).Returns(senderMock.Object);
    senderMock.Setup(s => s.CreateEmail()).Returns(messageMock.Object);
}

And this really isn’t very nice, right? Well, it doesn’t have to be like that!

First I’ll show you how it is used:

[SetUp]
public void SetUp()
{
    var messageMock = new Mock<IFluentEmailMessage>().AutoMockFluentInterface();
    var senderMock = new Mock<IFluentEmailSender>().AutoMockFluentInterface();

    messageMock.Setup(m => m.Done()).Returns(senderMock.Object);

    senderMock.Setup(s => s.CreateEmail()).Returns(messageMock.Object);
}

Much nicer! So, what’s happening?

  • Line 12 - We get a MethodInfo for the IsAny method on It. This will be used later on.
  • Line 13 - Create an expression instance for the generic type T, this seems to be the left half of a lambda (something => something…).
  • Line 16 - Get all the methods on T that return T.
  • Lines 18-31 - Go through all the methods obtained at line 16.
  • Line 20 - Get the parameters for the method.
  • Line 21-24 - Go through the parameters and make the call to IsAny a closed generic on the type parameter using the MethodInfo from line 12 (e.g. *It.IsAny()*).
  • Line 27-30 - Programmatically create a Lambda for the method on the interface.

The biggest trick I found in doing this was using an older version of IlSpy to decompile a known set of tests that had lambdas defining expectations.

One thing to note; if you are specifically interested in the values passed to the methods then you will need to do a .Verify() on the mock object.