How to mock static methods in c# using MOQ framework?

C#Unit TestingMockingMoq

C# Problem Overview


I have been doing unit testing recently and I've successfully mocked various scenarios using MOQ framework and MS Test. I know we can't test private methods but I want to know if we can mock static methods using MOQ.

C# Solutions


Solution 1 - C#

Moq (and other DynamicProxy-based mocking frameworks) are unable to mock anything that is not a virtual or abstract method.

Sealed/static classes/methods can only be faked with Profiler API based tools, like Typemock (commercial) or Microsoft Moles (free, known as Fakes in Visual Studio 2012 Ultimate /2013 /2015).

Alternatively, you could refactor your design to abstract calls to static methods, and provide this abstraction to your class via dependency injection. Then you'd not only have a better design, it will be testable with free tools, like Moq.

A common pattern to allow testability can be applied without using any tools altogether. Consider the following method:

public class MyClass
{
    public string[] GetMyData(string fileName)
    {
        string[] data = FileUtil.ReadDataFromFile(fileName);
        return data;
    }
}

Instead of trying to mock FileUtil.ReadDataFromFile, you could wrap it in a protected virtual method, like this:

public class MyClass
{
    public string[] GetMyData(string fileName)
    {
        string[] data = GetDataFromFile(fileName);
        return data;
    }

    protected virtual string[] GetDataFromFile(string fileName)
    {
        return FileUtil.ReadDataFromFile(fileName);
    }
}

Then, in your unit test, derive from MyClass and call it TestableMyClass. Then you can override the GetDataFromFile method to return your own test data.

Hope that helps.

Solution 2 - C#

Another option to transform the static method into a static Func or Action. For instance.

Original code:

    class Math
    {
        public static int Add(int x, int y)
        {
            return x + y;
        }

You want to "mock" the Add method, but you can't. Change the above code to this:

        public static Func<int, int, int> Add = (x, y) =>
        {
            return x + y;
        };

Existing client code doesn't have to change (maybe recompile), but source stays the same.

Now, from the unit-test, to change the behavior of the method, just reassign an in-line function to it:

    [TestMethod]
    public static void MyTest()
    {
        Math.Add = (x, y) =>
        {
            return 11;
        };

Put whatever logic you want in the method, or just return some hard-coded value, depending on what you're trying to do.

This may not necessarily be something you can do each time, but in practice, I found this technique works just fine.

[edit] I suggest that you add the following Cleanup code to your Unit Test class:

    [TestCleanup]
    public void Cleanup()
    {
        typeof(Math).TypeInitializer.Invoke(null, null);
    }

Add a separate line for each static class. What this does is, after the unit test is done running, it resets all the static fields back to their original value. That way other unit tests in the same project will start out with the correct defaults as opposed your mocked version.

Solution 3 - C#

Moq cannot mock a static member of a class.

When designing code for testability it's important to avoid static members (and singletons). A design pattern that can help you refactoring your code for testability is Dependency Injection.

This means changing this:

public class Foo
{
    public Foo()
    {
        Bar = new Bar();
    }
}

to

public Foo(IBar bar)
{
    Bar = bar;
}

This allows you to use a mock from your unit tests. In production you use a Dependency Injection tool like Ninject or Unity wich can wire everything together.

I wrote a blog about this some time ago. It explains which patterns an be used for better testable code. Maybe it can help you: Unit Testing, hell or heaven?

Another solution could be to use the Microsoft Fakes Framework. This is not a replacement for writing good designed testable code but it can help you out. The Fakes framework allows you to mock static members and replace them at runtime with your own custom behavior.

Solution 4 - C#

As mentioned in the other answers MOQ cannot mock static methods and, as a general rule, one should avoid statics where possible.

Sometimes it is not possible. One is working with legacy or 3rd party code or with even with the BCL methods that are static.

A possible solution is to wrap the static in a proxy with an interface which can be mocked

    public interface IFileProxy {
        void Delete(string path);
    }

    public class FileProxy : IFileProxy {
        public void Delete(string path) {
            System.IO.File.Delete(path);
        }
    }

    public class MyClass {

        private IFileProxy _fileProxy;

        public MyClass(IFileProxy fileProxy) {
            _fileProxy = fileProxy;
        }

        public void DoSomethingAndDeleteFile(string path) {
            // Do Something with file
            // ...
            // Delete
            System.IO.File.Delete(path);
        }

        public void DoSomethingAndDeleteFileUsingProxy(string path) {
            // Do Something with file
            // ...
            // Delete
            _fileProxy.Delete(path);

        }
    }

The downside is that the ctor can become very cluttered if there are a lot of proxies (though it could be argued that if there are a lot of proxies then the class may be trying to do too much and could be refactored)

Another possibility is to have a 'static proxy' with different implementations of the interface behind it

   public static class FileServices {

        static FileServices() {
            Reset();
        }

        internal static IFileProxy FileProxy { private get; set; }

        public static void Reset(){
           FileProxy = new FileProxy();
        }

        public static void Delete(string path) {
            FileProxy.Delete(path);
        }

    }

Our method now becomes

    public void DoSomethingAndDeleteFileUsingStaticProxy(string path) {
            // Do Something with file
            // ...
            // Delete
            FileServices.Delete(path);

    }

For testing, we can set the FileProxy property to our mock. Using this style reduces the number of interfaces to be injected but makes dependencies a bit less obvious (though no more so than the original static calls I suppose).

Solution 5 - C#

We commonly mock instance (non-static) classes and their methods by depending on abstractions like interfaces instead of directly depending on the concrete class.

We can do the same with static methods. Here's an example of a class that depends on a static method. (This is horribly contrived.) In this example we depend directly on the static method, so we can't mock it.

public class DoesSomething
{
    public long AddNumbers(int x, int y)
    {
        return Arithemetic.Add(x, y); // We can't mock this :(
    }
}

public static class Arithemetic
{
    public static long Add(int x, int y) => x + y;
}

In order to be able to mock the Add method we can inject an abstraction. Instead of injecting an interface, we can inject a Func<int, int, long> or a delegate. Either work, but I prefer a delegate because we can give it a name that says what it's for and distinguishes it from other functions with the same signature.

Here's the delegate and what the class looks like when we inject the delegate:

public delegate long AddFunction(int x, int y);

public class DoesSomething
{
    private readonly AddFunction _addFunction;

    public DoesSomething(AddFunction addFunction)
    {
        _addFunction = addFunction;
    }

    public long AddNumbers(int x, int y)
    {
        return _addFunction(x, y);
    }
}

This works exactly the same way as when we inject interfaces into classes' constructors.

We can use Moq to create a mock for the delegate just like we do with interfaces.

var addFunctionMock = new Mock<AddFunction>();
addFunctionMock.Setup(_ => _(It.IsAny<int>(), It.IsAny<int>())).Returns(2);
var sut = new DoesSomething(addFunctionMock.Object);

...but that syntax is verbose and hard to read. I had to Google it. It's much easier if we use an anonymous function instead of Moq:

AddFunction addFunctionMock = (x, y) => 2;
var sut = new DoesSomething(addFunctionMock);

We can use any method that has the correct signature. If we wanted to we could define another method in our test class with that signature and use that.


As a side point, if we inject a delegate, how do we set that up with our IoC container? It looks just like registering an interface and implementation. Using IServiceCollection:

serviceCollection.AddSingleton<AddFunction>(Arithemetic.Add);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHimanshuView Question on Stackoverflow
Solution 1 - C#Igal TabachnikView Answer on Stackoverflow
Solution 2 - C#zumalifeguardView Answer on Stackoverflow
Solution 3 - C#Wouter de KortView Answer on Stackoverflow
Solution 4 - C#AlanTView Answer on Stackoverflow
Solution 5 - C#Scott HannenView Answer on Stackoverflow