Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock static property with moq

I am pretty new to use moq. I am into creating some unit test case to HttpModule and everything works fine until I hit a static property as follows

this.applicationPath = (HttpRuntime.AppDomainAppVirtualPath.Length > 1) ? HttpRuntime.AppDomainAppVirtualPath : String.Empty;

I do not know how create mocks for static class and property like HttpRuntime.AppDomainAppVirtualPath. The context, request and response have been mocked well with sample code I get from moq. I will appreciate if somebody can help me on this.

like image 263
jyothish george Avatar asked Mar 10 '10 11:03

jyothish george


People also ask

Can you mock a static class Moq?

You can use Moq to mock non-static methods but it cannot be used to mock static methods.

Can we mock static field?

For Mockito, there is no direct support to mock private and static methods. In order to test private methods, you will need to refactor the code to change the access to protected (or package) and you will have to avoid static/final methods.

Can you mock a class with Moq?

You can use Moq to create mock objects that simulate or mimic a real object. Moq can be used to mock both classes and interfaces. However, there are a few limitations you should be aware of. The classes to be mocked can't be static or sealed, and the method being mocked should be marked as virtual.

What can be mocked with Moq?

Unit testing is a powerful way to ensure that your code works as intended. It's a great way to combat the common “works on my machine” problem. Using Moq, you can mock out dependencies and make sure that you are testing the code in isolation. Moq is a mock object framework for .


3 Answers

Moq can't fake static members.

As a solution you can create a wrapper class (Adapter Pattern) holding the static property and fake its members.
For example:

public class HttpRuntimeWrapper {     public virtual string AppDomainAppVirtualPath      {          get         {              return HttpRuntime.AppDomainAppVirtualPath;          }     } } 

In the production code you can access this class instead of HttpRuntime and fake this property:

[Test] public void AppDomainAppVirtualPathTest() {     var mock = new Moq.Mock<HttpRuntimeWrapper>();     mock.Setup(fake => fake.AppDomainAppVirtualPath).Returns("FakedPath");      Assert.AreEqual("FakedPath", mock.Object.AppDomainAppVirtualPath); } 

Another solution is to use Isolation framework (as Typemock Isolator) in which you can fake static classes and members.
For example:

Isolate.WhenCalled(() => HttpRuntime.AppDomainAppVirtualPath)        .WillReturn("FakedPath"); 

Disclaimer - I work at Typemock

like image 192
Elisha Avatar answered Sep 16 '22 11:09

Elisha


You cannot Moq static methods with Moq.

This is not a bad thing in reality, static methods and classes do have their place but for logic they make unit testing difficult. Naturally you'll run into them when using other libraries. To get around this you'll need to write an adapter (wrapper) around the static code, and provide an interface. For example:

// Your static class - hard to mock class StaticClass {    public static int ReturnOne()     {        return 1;    } }  // Interface that you'll use for a wrapper interface IStatic {     int ReturnOne(); } 

Note, I've ommited the concrete class that uses IStatic for the production code. All it would be is a class which uses IStatic and your production code would make use of this class, rather than StaticClass above.

Then with Moq:

var staticMock = new Mock<IStatic>(); staticMock.Setup(s => s.ReturnOne()).Returns(2); 
like image 44
Finglas Avatar answered Sep 16 '22 11:09

Finglas


As mentioned in previous answers, you can't use MoQ on static methods, and if you need to, your best shot is to create a wrapper around the static class.

However, something I've discovered recently is the Moles project. From the homepage; "Moles allows to replace any .NET method with a delegate. Moles supports static or non-virtual methods." It might be useful for your current situation.

like image 21
Kirschstein Avatar answered Sep 19 '22 11:09

Kirschstein