UrlHelper class throws null exception in Asp.net mvc

1.2k Views Asked by At

I am developing an Asp.net mvc web application. I am doing Unit Test to my application. I am using Moq to mock objects. I am trying to mock Url helper class. I found this link- asp.net mvc: how to mock Url.Content("~")?. Using that class, I can mock UrlHelper class in unit test.

I created a BaseController like this

public class BaseController : Controller
{
    private IUrlHelper _urlHelper;

    public new IUrlHelper Url
    {
        get { return _urlHelper; }
        set { _urlHelper = value; }
    }
}

Here is the IUrlHelper interface/abstraction

public interface IUrlHelper
{
    string Action(string actionName);
    string Action(string actionName, object routeValues);
    string Action(string actionName, string controllerName);
    string Action(string actionName, RouteValueDictionary routeValues);
    string Action(string actionName, string controllerName, object routeValues);
    string Action(string actionName, string controllerName, RouteValueDictionary routeValues);
    string Action(string actionName, string controllerName, object routeValues, string protocol);
    string Action(string actionName, string controllerName, RouteValueDictionary routeValues, string protocol, string hostName);
    string Content(string contentPath);
    string Encode(string url);
    string RouteUrl(object routeValues);
    string RouteUrl(string routeName);
    string RouteUrl(RouteValueDictionary routeValues);
    string RouteUrl(string routeName, object routeValues);
    string RouteUrl(string routeName, RouteValueDictionary routeValues);
    string RouteUrl(string routeName, object routeValues, string protocol);
    string RouteUrl(string routeName, RouteValueDictionary routeValues, string protocol, string hostName);
}

I mock the Url.Content() in the unit test like this

Mock<IUrlHelper> urlHelperMock = new Mock<IUrlHelper>();
urlHelperMock
    .Setup(x => x.Content(It.IsAny<string>()))
    .Returns<string>(x => "~/" + x);// Mock Content method of Url Helper

Test run successfully and working fine. The problem is I cannot use it in real time application. I mean when I run my app and call Url.Content("path"), it throws null exception.

For example

public class ExampleController : BaseController
{
    public string GetPath()
    {
       return Url.Content("~/Path/To/File");
    }
}

Url.Content in this code throws null exception. It is working fine in unit test. How can I fix that code?

1

There are 1 best solutions below

0
On BEST ANSWER

In this case there really isn't a need to abstract the UrlHelper. Just mock up the helper for the test to do what is required.

For example, assuming

public class ExampleController : Controller {
    public string GetContent() {
       return Url.Content("~/Path/To/File");
    }
}

Here is a test that mocks the UrlHelper using moq to work just like in original example

[TestClass]
public class UrlHelperTest {
    [TestMethod]
    public void MockUrlHelper() {
        //Arrange            
        var expectedPath = "~/Path/To/File";
        var expectedContent = "<p>Fake content here<p>";
        var urlHelperMock = new Mock<UrlHelper>();
        urlHelperMock
            .Setup(m => m.Content(expectedPath))
            .Returns(expectedContent)
            .Verifiable();

        var sut = new ExampleController();
        sut.Url = urlHelperMock.Object; //Set mock UrlHelper        

        //Act
        var actualContent = sut.GetContent();

        //Assert
        urlHelperMock.Verify();
        Assert.AreEqual(expectedContent, actualContent);
    }
}

So now the test can be performed and also the framework will populate the necessary controller properties in production because technically nothing was changed from the original framework to custom abstractions.