I run unit tests of code that uses VirtualParthUtility.GetAbsolute, but I am having trouble mocking the context for this.
I set the layout with Moq as follows
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; }
And tied it to the MVC controller
_myController.ControllerContext = new ControllerContext(MakeMockHttpContext("~/").Object, new RouteData(), _slideSelectorController);
The code that runs during the test falls into the line:
venue.StyleSheetUrl = VirtualPathUtility.ToAbsolute(venue.StyleSheetUrl); // input like "~/styles/screen.css"
Each time this is executed, it goes to System.Web.VirtualPathUtility, with the problem that the returned "VirtualParthString" always throws an exception:
public static string ToAbsolute(string virtualPath) { return VirtualPath.CreateNonRelative(virtualPath).VirtualPathString; }
The reason for the exception is easy to see in 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; } }
Through the viewport, I see that _virtualPath and HttpRuntime.AppDomainAppVirtualPathString are zero, so it throws an exception.
If _virtualPath is set, an exception will not occur. But after the VirtualPath.Create method has created a new VirtualPath object, it does not set the _virtualPath property until it is returned. Excerpt from Create method up to this point:
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;
So, if anyone can suggest how to do a unit test, this will be very helpful!
Thanks,
Steve