Unit testing MVC controller - need path to the application

1

I've inherited a legacy ASP.net MVC application and I'm trying to backfit unit test and running into an error. Here's my unit test:

public void DashboardController_Index_ReturnsIndex()
     {
         var dashboardController = _mocker.Resolve<DashboardController>();
         var controllerContextMock = new Mock<ControllerContext>();
         var userMock = new Mock<IUserContext>();

         userMock
             .SetupGet(u => u.Identity.IsAuthenticated)
             .Returns(true);
         userMock
             .Setup(u => u.Type)
             .Returns(EUserType.Normal);
         controllerContextMock
             .SetupGet(c => c.HttpContext.User)
             .Returns(userMock.Object);
         controllerContextMock
             .SetupGet(p => p.HttpContext.Request.Url)
             .Returns(new Uri("http://localhost/Dashboard/Index"));

         dashboardController.ControllerContext = controllerContextMock.Object;

         var result = dashboardController.Index() as ViewResult;

         Assert.Equal("Index", result.ViewName);
     }

When the Index action is called, it calls a static method in another class that returns a string expression used for configuration purposes. After that config string gets returned, another static method in another (referenced) static class (different namespace) gets called which attempts to parse that string expression but throws an exception. Here's that method:

private static string GetResourceString(HttpContextBase httpContext, string sxExpression, string sxVirtualPath)
        {
            var context = new ExpressionBuilderContext(sxVirtualPath);
            var builder = new ResourceExpressionBuilder();
            var fields = (ResourceExpressionFields)builder.ParseExpression(sxExpression, 
                typeof(string), context);

            if (string.IsNullOrEmpty(fields.ClassKey) == false)
                return (string)httpContext.GetGlobalResourceObject(fields.ClassKey, fields.ResourceKey, 
                    Thread.CurrentThread.CurrentCulture);
            return (string)httpContext.GetLocalResourceObject(sxVirtualPath, fields.ResourceKey, 
                Thread.CurrentThread.CurrentCulture);
        }

The exception occurs in the third line of this method where the code attempts to break the string into fields. Specifically, here's the exception:

System.Web.HttpException (0x80004005): The application relative virtual path '~/' cannot be made absolute, because the path to the application is not known.

I've seen this post that describes how to inject a fake into this call but since the Controller itself isn't trying to parse the string, but rather handing it off to a helper method in another class, it seems that DI won't work. Any idea how I can fake the application path while unit testing? In production, this code works just fine. I'm thinking I can refactor the controller to use this helper class as a dependency instead of just calling static methods but I'm hoping for a solution that doesn't require code changes to production code.

c#
asp.net-mvc
unit-testing
asked on Stack Overflow Feb 19, 2020 by Scott Reeves • edited Feb 19, 2020 by Scott Reeves

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0