How to mock static methods in c# using MOQ framework?
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.
Mock Static class using moq
There are two ways to accomplish this - As PSGuy said you can create an Interface that your code can rely on, then implement a concrete that simply calls the static method or any other logging implementation like NLog. This is the ideal choice. In addition to this if you have lots of code calling the static method that needs to be tested you can refactor your static method to be mocked.
Assuming your static class looks something like this:
public static class AppLog
{
public static void LogSomething(...) { ... }
}
You can introduce a public static property that is an instance of the Interface mentioned above.
public static class AppLog
{
public static ILogger Logger = new Logger();
public static void LogSomething(...)
{
Logger.LogSomething(...);
}
}
Now any code dependent on this static method can be tested.
public void Test()
{
AppLog.Logger = Substitute.For<ILogger>(); // NSubstitute
var logMock = new Mock<ILogger>(); // Moq
AppLog.Logger = logMock.Object; // Moq
SomeMethodToTest();
AppLog.Logger.Recieved(1).LogSomething(...); // NSubstitute
logMock.Verify(x => x.LogSomething(...)); // Moq
}
Mocking Static Methods
Mocking frameworks like Moq or Rhinomocks can only create mock instances of objects, this means mocking static methods is not possible.
You can also search Google for more info.
Also, there's a few questions previously asked on StackOverflow here, here and here.
Why mocking a Repository requires a virtual function and mocking IRepository overrides the existing function?
Any kind of mocking relies on members to be overridable. Your mocking-framework will create some class that either implements your interface or overrides your class. So what the framework creates is similar to the following:
class WeirdClassName : IRepository
{
string GetString(object o) => "SomeString";
}
or if your member would be a class-member this:
class WeirdClassName : Repository
{
string override GetString(object o) => "SomeString";
}
Interface-members are implictely overridable, as they literally do not provide any own logic. You can allways provide your own implementation for it. Class-members are only overridable, if they are virtual
.
In your case there seems to be some difference in the test depending on if you mock the interface or the class. That probably indicates your test depends on some internals of the class - e.g. some initialization on the repo. You should either mock that also, or decouple your test from that dependency.
Is there any free mocking framework that can mock static methods and sealed classes?
Not really, but you can use Moq Moq Download or Rhino Mocks Rhino Mocks Download to wrap the static method and call in a virtual instance method in another class
Mocking Static methods using Rhino.Mocks
Related Topics
Retrieving Creation Date of File (Ftp)
How to Handle Session End in Global.Asax
How Is Performance Affected by an Unused Using Directive
Understanding .Asenumerable() in Linq to SQL
How to Serialize Nested Properties to My Class in One Operation with JSON.Net
Listbox Items Return String, When Datatemplate Is Button
How to Modify or Delete Items from an Enumerable Collection While Iterating Through It in C#
How to Hide a Column (Gridview) But Still Access Its Value
Recursive Hierarchy - Recursive Query Using Linq
Convert Array of Bytes to Bitmapimage
Why Was "Switchto" Removed from Async Ctp/Release
Using Layers and Bitmask with Raycast in Unity
How to Convert Ticks to a Date Format
Configure JSON.Net to Ignore Datacontract/Datamember Attributes
Handling Exceptions, Is This a Good Way