Как смоделировать контекст во время модульного тестирования кода с помощью метода VirtualPathUtility.GetAbsolute
Я запускаю модульные тесты для кода, который использует VirtualParthUtility.GetAbsolute, но у меня возникают проблемы с имитацией контекста, чтобы это работало.
Я создал макет контекста с Moq следующим образом
private Mock<HttpContextBase> MakeMockHttpContext(string url) // url = "~/"
{
var mockHttpContext = new Mock<HttpContextBase>();
// Mock the request
var mockRequest = new Mock<HttpRequestBase>();
mockRequest.Setup(x => x.ApplicationPath).Returns("/");
mockRequest.Setup(x => x.Path).Returns("/");
mockRequest.Setup(x => x.PathInfo).Returns(string.Empty);
mockRequest.Setup(x => x.AppRelativeCurrentExecutionFilePath).Returns(url);
mockHttpContext.Setup(x => x.Request).Returns(mockRequest.Object);
// Mock the response
var mockResponse = new Mock<HttpResponseBase>();
mockResponse.Setup(x => x.ApplyAppPathModifier(It.IsAny<string>())).Returns((string s) => s);
mockHttpContext.Setup(x => x.Response).Returns(mockResponse.Object);
return mockHttpContext;
}
И прикрепил это к контроллеру MVC
_myController.ControllerContext = new ControllerContext(MakeMockHttpContext("~/").Object, new RouteData(), _slideSelectorController);
Код, который запускается во время теста, попадает в строку:
venue.StyleSheetUrl = VirtualPathUtility.ToAbsolute(venue.StyleSheetUrl); // input like "~/styles/screen.css"
Каждый раз, когда он запускается, он входит в System.Web.VirtualPathUtility, с проблемой, что возвращаемое "VirtualParthString" всегда вызывает исключение:
public static string ToAbsolute(string virtualPath)
{
return VirtualPath.CreateNonRelative(virtualPath).VirtualPathString;
}
Причину исключения легко увидеть в System.Web.VirtualPathString:
public string VirtualPathString
{
get
{
if (this._virtualPath == null)
{
if (HttpRuntime.AppDomainAppVirtualPathObject == null)
{
throw new HttpException(System.Web.SR.GetString("VirtualPath_CantMakeAppAbsolute", new object[] { this._appRelativeVirtualPath }));
}
if (this._appRelativeVirtualPath.Length == 1)
{
this._virtualPath = HttpRuntime.AppDomainAppVirtualPath;
}
else
{
this._virtualPath = HttpRuntime.AppDomainAppVirtualPathString + this._appRelativeVirtualPath.Substring(2);
}
}
return this._virtualPath;
}
}
Через окно просмотра я вижу, что _virtualPath и HttpRuntime.AppDomainAppVirtualPathString оба равны NULL, следовательно, он выдает исключение.
Если установлен _virtualPath, исключение не произойдет. Но после того, как метод VirtualPath.Create создал новый объект VirtualPath, он не устанавливает свойство _virtualPath до его возвращения. Выдержка из метода Create до этого момента:
VirtualPath path = new VirtualPath();
if (UrlPath.IsAppRelativePath(virtualPath))
{
virtualPath = UrlPath.ReduceVirtualPath(virtualPath);
if (virtualPath[0] == '~')
{
if ((options & VirtualPathOptions.AllowAppRelativePath) == 0)
{
throw new ArgumentException(System.Web.SR.GetString("VirtualPath_AllowAppRelativePath", new object[] { virtualPath }));
}
path._appRelativeVirtualPath = virtualPath;
return path;
Так что если кто-нибудь может подсказать, как заставить работать этот модульный тест, это будет очень полезно!
Спасибо,
Стив
1 ответ
Я бы просто создал интерфейс-обертку. Что-то вроде:
public interface IPathUtilities
{
string ToAbsolute(string virtualPath);
}
Вы можете ввести это в свой контроллер. Во время теста используйте заглушку. Во время выполнения у вас будет класс, который реализует IPathUtilities
и звонки VirtualPathUtility.ToAbsolute()
,