Search code examples
c#unit-testingmockingmoq

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


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.


Solution

  • 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.