Home » c# » How do I use Moq to mock an extension method?

How do I use Moq to mock an extension method?

Posted by: admin November 30, 2017 Leave a comment

Questions:

I am writing a test that depends on the results of an extension method but I don’t want a future failure of that extension method to ever break this test. Mocking that result seemed the obvious choice but Moq doesn’t seem to offer a way to override a static method (a requirement for an extension method). There is a similar idea with Moq.Protected and Moq.Stub, but they don’t seem to offer anything for this scenario. Am I missing something or should I be going about this a different way?

Here is a trivial example that fails with the usual “Invalid expectation on a non-overridable member”. This is a bad example of needing to mock an extension method, but it should do.

public class SomeType {
    int Id { get; set; }
}

var ListMock = new Mock<List<SomeType>>();
ListMock.Expect(l => l.FirstOrDefault(st => st.Id == 5))
        .Returns(new SomeType { Id = 5 });

As for any TypeMock junkies that might suggest I use Isolator instead: I appreciate the effort since it looks like TypeMock could do the job blindfolded and inebriated, but our budget isn’t increasing any time soon.

Answers:

Extension methods are just static methods in disguise. Mocking frameworks like Moq or Rhinomocks can only create mock instances of objects, this means mocking static methods is not possible.

Questions:
Answers:

If you control the definition of the extension methods (i.e. they are not the LINQ built-in ones), there’s another alternative, explained at http://blogs.clariusconsulting.net/kzu/making-extension-methods-amenable-to-mocking/ “Making extension methods amenable to mocking”]1

Questions:
Answers:

I know this question hasn’t been active for about a year but Microsoft released a framework to handle exactly this called Moles.

Here are a few tutorials as well:

  • DimeCasts.net
  • Nikolai Tillman’s Tutorial

  • Questions:
    Answers:

    I created a wrapper class for the extension methods that I needed to mock.

    public static class MyExtensions
    {
        public static string MyExtension<T>(this T obj)
        {
            return "Hello World!";
        }
    }
    
    public interface IExtensionMethodsWrapper
    {
        string MyExtension<T>(T myObj);
    }
    
    public class ExtensionMethodsWrapper : IExtensionMethodsWrapper
    {
        public string MyExtension<T>(T myObj)
        {
            return myObj.MyExtension();
        }
    }
    

    Then you can mock the wrapper methods in your tests and code with your IOC container.

    Questions:
    Answers:

    If you can change the extension methods code then you can code it like this to be able to test:

    using System;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Moq;
    
    public static class MyExtensions
    {
        public static IMyImplementation Implementation = new MyImplementation();
    
        public static string MyMethod(this object obj)
        {
            return Implementation.MyMethod(obj);
        }
    }
    
    public interface IMyImplementation
    {
        string MyMethod(object obj);
    }
    
    public class MyImplementation : IMyImplementation
    {
        public string MyMethod(object obj)
        {
            return "Hello World!";
        }
    }
    

    So the extention methods are only a wrapper around the implementation interface.

    (You could use just the implementation class without extension methods which are sort of syntactic sugar.)

    And you can mock the implementation interface and set it as implementation for the extensions class.

    public class MyClassUsingExtensions
    {
        public string ReturnStringForObject(object obj)
        {
            return obj.MyMethod();
        }
    }
    
    [TestClass]
    public class MyTests
    {
        [TestMethod]
        public void MyTest()
        {
            // Given:
            //-------
            var mockMyImplementation = new Mock<IMyImplementation>();
    
            MyExtensions.Implementation = mockMyImplementation.Object;
    
            var myObject = new Object();
            var myClassUsingExtensions = new MyClassUsingExtensions();
    
            // When:
            //-------
            myClassUsingExtensions.ReturnStringForObject(myObject);
    
            //Then:
            //-------
            // This would fail because you cannot test for the extension method
            //mockMyImplementation.Verify(m => m.MyMethod());
    
            // This is success because you test for the mocked implementation interface
            mockMyImplementation.Verify(m => m.MyMethod(myObject));
        }
    }
    

    Questions:
    Answers:

    For extension methods I normally use the following approach:

    public static class MyExtensions
    {
        public static Func<int,int, int> _doSumm = (x, y) => x + y;
    
        public static int Summ(this int x, int y)
        {
            return _doSumm(x, y);
        }
    }
    

    It allows to inject _doSumm fairly easy.