Mocking Extension Methods with Moq

Viewed 177343

I have a preexisting Interface...

public interface ISomeInterface
{
    void SomeMethod();
}

and I've extended this intreface using a mixin...

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

I have a class thats calling this which I want to test...

public class Caller
{
    private readonly ISomeInterface someInterface;

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

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

and 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();
    }

Running this test however generates an exception...

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

My question is, is there a nice way to mock out the mixin call?

8 Answers

If you just want to make sure that the extension method was invoked, and you aren't trying to setup a return value, then you can check the Invocations property on the mocked object.

Like this:

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

Reason why it is not possible to mock an extension method is already given in good answers. I am just trying to give another possible solution with this answer: Extract a protected, virtual method with the call to the extension method and create a setup for this method in the test class/method by using a proxy.

public class Foo
{
  public void Method()
    => CallToStaticMethod();

  protected virtual void CallToStaticMethod()
    => StaticClass.StaticMethod();
}

and test

[TestMethod]
    public void MyTestMethod()
    {
        var expected = new Exception("container exception");
        var proxy = new Mock<Foo>();
        proxy.Protected().Setup("CallToStaticMethod").Throws(expected);

        var actual = Assert.ThrowsException<Exception>(() => proxy.Object.Foo());

        Assert.AreEqual(expected, actual);
    }
  

In my case extension method is a method around some public method of my class. So I checked call of that internal method. That approach is similar to Alvis answer (above).

So if you are using Moq, and want to mock the result of an Extension method, then you can use SetupReturnsDefault<ReturnTypeOfExtensionMethod>(new ConcreteInstanceToReturn()) on the instance of the mock class that has the extension method you are trying to mock.

It is not perfect, but for unit testing purposes it works well.

Related