2011-09-24 95 views
6

我正在对使用VirtualParthUtility.GetAbsolute的代码运行单元测试,但有问题模拟上下文以使其工作。如何在使用VirtualPathUtility.GetAbsolute方法单元测试代码时模拟上下文

我已经建立了一个模拟情境与起订量如下

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,问题是“VirtualP arthString”总是被退回抛出一个异常:

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属性。从创建方法的提取物到这一点是:

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; 

因此,如果任何人都可以建议如何得到这个单元测试工作,那将是非常有帮助!

感谢,

史蒂夫

+0

阅读,也许我需要使用隔离框架来嘲笑静态方法HttpRuntime.AppDomainAppVirtualPath? – Appetere

回答

5

我只想创造一个包装接口。例如:

public interface IPathUtilities 
{ 
    string ToAbsolute(string virtualPath); 
} 

您可以将其注入控制器。在测试时间,使用存根。在运行时,您将拥有一个实现IPathUtilities的类并调用VirtualPathUtility.ToAbsolute()

+0

感谢您的建议。漂亮优雅的解决 – Appetere

+0

如果你喜欢这个答案,请将其标记为可接受的解决方案。谢谢! – PatrickSteele

相关问题