How to Mock Static Methods in C# Using Moq Framework

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



Leave a reply



Submit