Модульное тестирование MVC контроллера - нужен путь к приложению - PullRequest
1 голос
/ 19 февраля 2020

Я унаследовал устаревшее приложение ASP. net MVC, и я пытаюсь выполнить модульное тестирование с обратной совместимостью и столкнулся с ошибкой. Вот мой модульный тест:

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);
     }

Когда вызывается действие Index, он вызывает метод stati c в другом классе, который возвращает строковое выражение, используемое в целях конфигурации. После возвращения этой строки конфигурации вызывается другой метод stati c в другом (указанном) классе stati c (другое пространство имен), который пытается проанализировать это строковое выражение, но выдает исключение. Вот этот метод:

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);
        }

Исключение возникает в третьей строке этого метода, когда код пытается разбить строку на поля. В частности, вот исключение:

System.Web.HttpException (0x80004005): относительный виртуальный путь к приложению '~ /' нельзя сделать абсолютным, поскольку путь к приложению неизвестен.

Я видел в этом посте , который описывает, как вставить фальшивку в этот вызов, но так как сам контроллер не пытается проанализировать строку, а передает ее вспомогательный метод в другом классе, кажется, что DI не будет работать. Любая идея, как я могу подделать путь приложения во время модульного тестирования? В производстве этот код работает просто отлично. Я думаю, что могу реорганизовать контроллер для использования этого вспомогательного класса в качестве зависимости вместо простого вызова методов stati c, но я надеюсь на решение, которое не требует изменений кода в производственном коде.

...