2011-09-24 14 views
6

Sono in esecuzione test di unità sul codice che utilizza VirtualParthUtility.GetAbsolute, ma sto riscontrando problemi di simulazione del contesto perché funzioni.Come simulare il contesto mentre il codice di test unitario utilizza il metodo VirtualPathUtility.GetAbsolute

ho creato un contesto finto con Moq come segue

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

e attaccato l'accaduto a un controller MVC

_myController.ControllerContext = new ControllerContext(MakeMockHttpContext("~/").Object, new RouteData(), _slideSelectorController); 

Il codice che viene eseguito durante il test colpisce la linea:

Ogni volta che viene eseguito, passa a System.Web.VirtualPathUtility, con il problema che "VirtualP arthString" da restituire sempre genera un'eccezione:

public static string ToAbsolute(string virtualPath) 
{ 
    return VirtualPath.CreateNonRelative(virtualPath).VirtualPathString; 
} 

Il motivo per l'eccezione è facile da vedere 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; 
    } 
} 

Attraverso la finestra di controllo posso vedere che _virtualPath e HttpRuntime.AppDomainAppVirtualPathString sono entrambi nulli, quindi genera un'eccezione.

Se è stato impostato _virtualPath, l'eccezione non si verifica. Ma dopo che il metodo VirtualPath.Create ha creato un nuovo oggetto VirtualPath, non imposta la proprietà _virtualPath prima che venga restituita. Un estratto dal metodo Create fino a questo punto è:

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; 

Quindi, se qualcuno può suggerire come ottenere questo test di funzionamento dell'unità, che sarà molto utile!

Grazie,

Steve

+0

Leggendo intorno, forse ho bisogno di utilizzare un isolamento Framework per deridere il metodo statico HttpRuntime.AppDomainAppVirtualPath? – Appetere

risposta

5

vorrei solo creare un'interfaccia wrapper. Qualcosa del tipo:

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

È possibile iniettarlo nel controller. Al momento del test, utilizzare uno stub. A runtime, avrai una classe che implementa IPathUtilities e chiama VirtualPathUtility.ToAbsolute().

+0

Grazie per il suggerimento. Bella soluzione elegante. – Appetere

+0

Se ti piace questa risposta, contrassegnala come soluzione accettata. Grazie! – PatrickSteele

Problemi correlati