You can't. There's easy to remember rule about mocking - cannot override, cannot mock1. If you were deriving from Url
class, would you be able to override Action
method? No. Nor can Moq, Rhino, FakeItEasy or any other framework based on DynamicProxy.
Your options narrow the ones below:
- use different framework, not based on DynamicProxy (which usually means based on compiler services for advanced interception) - such tools are usually paid.
- wrap problematic call with interface / delegate and inject it to tested code (so that you can mock it using free framework)
How would the wrapping look like?
public interface IUrlWrapper
{
string Action(string name, object values);
}
// Wrapper Interface
public class TestedClass
{
private readonly IUrlWrapper url;
public TestedClass(IUrlWrapper urlWrapper)
{
this.url = urlWrapper;
}
// ...
return Json(new
{
redirectUrl = this.url.Action("Action", "Controller"),
isredirection = true
});
// ...
}
With such setup, you can use Moq without further issues. However, in single method call you can just as well use Func
delegate without any isolation framework:
// Func Delegate
public class TestedClass
{
private readonly Func<string, object, string> urlAction;
public TestedClass(Func<string, object, string> urlAction)
{
this.urlAction = urlAction;
}
// ...
return Json(new
{
redirectUrl = this.urlAction("Action", "Controller"),
isredirection = true
});
// ...
}
In your test, you simply create delegate on the fly.
1 I wrote a blog post going bit more into details of this very problem: How to mock private method with ...