Coder Perfect

Using Moq to Mock Extension Methods

Problem

I already have an interface…

public interface ISomeInterface
{
    void SomeMethod();
}

I’ve also added a mixin to this interface…

public static class SomeInterfaceExtensions
{
    public static void AnotherMethod(this ISomeInterface someInterface)
    {
        // Implementation here
    }
}

I have a class that calls this, and I’d like to test it…

public class Caller
{
    private readonly ISomeInterface someInterface;

    public Caller(ISomeInterface someInterface)
    {
        this.someInterface = someInterface;
    }

    public void Main()
    {
        someInterface.AnotherMethod();
    }
}

I’d like to mock the interface and verify the call to the extension method, as well as a test where I’d like to mock the interface and verify the call to the extension method…

    [Test]
    public void Main_BasicCall_CallsAnotherMethod()
    {
        // Arrange
        var someInterfaceMock = new Mock<ISomeInterface>();
        someInterfaceMock.Setup(x => x.AnotherMethod()).Verifiable();

        var caller = new Caller(someInterfaceMock.Object);

        // Act
        caller.Main();

        // Assert
        someInterfaceMock.Verify();
    }

However, running this test results in an exception…

System.ArgumentException: Invalid setup on a non-member method:
x => x.AnotherMethod()

I’m wondering whether there’s a good method to mimic out the mixin call.

Asked by Russell Giddings

Solution #1

To get around this issue, I employed a Wrapper. Make a wrapper object for your simulated method and provide it to it.

Paul Irwin’s Mocking Static Methods for Unit Testing contains several good examples.

Answered by Alvis

Solution #2

With the mocking framework, you can’t “directly” imitate a static method (thus the extension method). You can try Moles (http://research.microsoft.com/en-us/projects/pex/downloads.aspx), a free tool from Microsoft that implements a different approach. Here is the description of the tool:

Moles can be used with any testing framework (it is platform agnostic).

Answered by Daniele Armanasco

Solution #3

I discovered that I needed to look into the extension method for which I was trying to mimic the input and mock what was going on there.

Using an extension seemed to me to be the same as explicitly adding code to your method. This meant that instead of mocking the extension itself, I had to ridicule what occurred inside it.

Answered by chris31389

Solution #4

When I’m wrapping an object, I like to use the wrapper (adapter pattern). I’m not sure I’d wrap an extension method that isn’t part of the object with that.

I inject (swap out) the method using an internal Lazy Injectable Property of type Action, Func, Predicate, or Delegate.

    internal Func<IMyObject, string, object> DoWorkMethod
    {
        [ExcludeFromCodeCoverage]
        get { return _DoWorkMethod ?? (_DoWorkMethod = (obj, val) => { return obj.DoWork(val); }); }
        set { _DoWorkMethod = value; }
    } private Func<IMyObject, string, object> _DoWorkMethod;

Then, instead of calling the actual method, you call the Func.

    public object SomeFunction()
    {
        var val = "doesn't matter for this example";
        return DoWorkMethod.Invoke(MyObjectProperty, val);
    }

Check out http://www.rhyous.com/2016/08/11/unit-testing-calls-to-complex-extension-methods/ for a more detailed example.

Answered by Rhyous

Solution #5

You can check the Invocations property on the mimicked object if you just want to make sure the extension method was called without trying to set a return value.

Like this:

var invocationsCount = mockedObject.Invocations.Count;
invocationsCount.Should().BeGreaterThan(0);

Answered by Clinton Avery

Post is based on https://stackoverflow.com/questions/2295960/mocking-extension-methods-with-moq