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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With