I\'m doing some unit testing, and mocking some properties using Moq.
Now, this is a Controller test (ASP.NET MVC 3). My Controllers
"So....what i did is the only way?"
No not the only way - you are much better off implementing an interface and mocking that. Then your actual methods can be virtual or not as you choose.
Although, all that was said before is true, it's worth to know that the proxy-mocking approach (like the one that moq uses)i s not the only one possible.
Check http://www.typemock.com/ for a comprehensive, solution, that allows you to mock both sealed classes, non-virtual methods etc. Pretty powerful.
Moq and other similar mocking frameworks can only mock interfaces, abstract methods/properties (on abstract classes) or virtual methods/properties on concrete classes.
This is because it generates a proxy that will implement the interface or create a derived class that overrides those overrideable methods in order to intercept calls.
I've created an interface and wrapper class. e.g.
public interface IWebClient
{
string DownloadString(string url);
}
public class WebClient : IWebClient
{
private readonly System.Net.WebClient _webClient = new System.Net.WebClient();
public string DownloadString(string url)
{
return _webClient.DownloadString(url);
}
}
and then in your unit tests just mock out the interface:
var mockWebClient = new Mock<IWebClient>();
Obviously you may need to include more properties / methods. But does the trick.
Another useful trick for other mocking problems, such as modifying the current date time (I always use UTC date time):
public interface IDateTimeUtcNowProvider
{
DateTime UtcNow { get; }
}
public class DateTimeUtcNowProvider : IDateTimeUtcNowProvider
{
public DateTime UtcNow { get { return DateTime.UtcNow; } }
}
e.g. if you have a service that runs every x minutes you can just mock out the IDateTimeProvider and return a time that is later to check the service ran again... or whatever.