Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 585
Himanshu Avatar asked Sep 25 '12 09:09

Himanshu


People also ask

Can we mock static methods in C#?

You can use Moq to mock non-static methods but it cannot be used to mock static methods. Although static methods cannot be mocked easily, there are a few ways to mock static methods. You can take advantage of the Moles or Fakes framework from Microsoft to mock static method calls.

How do I mock a static method in Nunit?

Mocking Static Methods If you need to truly mock static methods, you need to use a commercial tool like Microsoft Fakes (part of Visual Studio Enterprise) or Typemock Isolator. Or, you can simply create a new class to wrap the static method calls, which itself can be mocked.

How do I make a static class MOQ?

Moq doesn't allow the mocking of static methods so you will probably need to change the working of the static method. One option is to have the static method call an instance method of a dependency. So you'll create a "Logger" class with a Log method and add a static Logger field / property (BusinessExceptionHandler.


1 Answers

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.

like image 118
Igal Tabachnik Avatar answered Sep 17 '22 12:09

Igal Tabachnik