2011-09-24 4 views
6

Używam testów jednostkowych kodu, który używa VirtualParthUtility.GetAbsolute, ale mam problemy z kpiny z kontekstu, aby to działało.Jak kpić z kontekstu podczas testowania kodu jednostkowego za pomocą metody VirtualPathUtility.GetAbsolute

mam założyć mock kontekstu z Min następująco

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

i dołączone do tego MVC Controller

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

kod, który działa podczas testu uderza linię:

venue.StyleSheetUrl = VirtualPathUtility.ToAbsolute(venue.StyleSheetUrl); // input like "~/styles/screen.css" 

Za każdym razem uruchamia się System.Web.VirtualPathUtility, z problemem polegającym na tym, że "VirtualP arthString”zostać zwrócone zawsze zgłasza wyjątek:

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

Powodem wyjątkiem jest łatwo zobaczyć w 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; 
    } 
} 

Przez Okno Watch widzę, że _virtualPath i HttpRuntime.AppDomainAppVirtualPathString mają wartość NULL, dlatego generuje wyjątek.

Jeśli ustawiono opcję _virtualPath, wyjątek nie będzie miał miejsca. Ale po tym, jak metoda VirtualPath.Create utworzyła nowy obiekt VirtualPath, nie ustawia właściwości _virtualPath, zanim zostanie zwrócona. Wyciąg z metody Create do tej pory to:

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; 

Więc jeśli ktoś może sugerować, jak zdobyć tę pracę jednostki testowej, które będą bardzo pomocne!

Dzięki,

Steve

+0

Czytanie w kółko, być może potrzebuję użyć Ramy izolowania do wyśmiewania statycznej metody HttpRuntime.AppDomainAppVirtualPath? – Appetere

Odpowiedz

5

Chciałbym po prostu utworzyć interfejs otoki. Coś jak:

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

Możesz wprowadzić to do kontrolera. W czasie testu użyj kodu pośredniczącego. W czasie wykonywania będziesz mieć klasę, która implementuje IPathUtilities i wywołuje VirtualPathUtility.ToAbsolute().

+0

Dzięki za sugestię. Ładne eleganckie rozwiązanie. – Appetere

+0

Jeśli podoba ci się ta odpowiedź, oznacz to jako zaakceptowane rozwiązanie. Dzięki! – PatrickSteele