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
Using Microsoft Fakes as suggested by @Sujith is a viable solution. Here is how you actually do it:
System.Web
in your reference of your test project and right clickSystem.Web.4.0.0.0.Fakes
Use following code:
using (Microsoft.QualityTools.Testing.Fakes.ShimsContext.Create()) { System.Web.Fakes.ShimHttpRuntime.AppDomainAppVirtualPathGet = () => "/"; // Do what ever needs the faked AppDomainAppVirtualPath }
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
You can use Microsoft Fakes for this. It will definitely solve the issue. Refer to https://msdn.microsoft.com/en-us/library/hh549175.aspx
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);
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.
Best solution I have found so far is Telerik's JustMock - unfortunately only the paid for version allows mocking of statics.
While the idea of wrapping statics is a good one - you can't always do this. If you want to test some code that uses some static classes already then it's not always possible to switch out and use a wrapper. In this case JustMock looks a reasonable solution and I'm probably going to use it on some solutions in the near future.