2013-06-18 11 views
6

Napisałem metodę, która konwertuje widok MVC na ciąg znaków i testuje metodę, aby sprawdzić, czy zwraca ciąg znaków.Metoda testowania jednostki konwertująca widok MVC na ciąg znaków przy użyciu metody view.render

Oczywiście działa z Web, ale kiedy uruchomię test w NUnit, generuje NullReferenceException w System.Web, gdy metoda próbuje wywołać View.Render.

Oto StackTrace:

w System.Web.VirtualPath.GetCacheKey() 
    w System.Web.Compilation.BuildManager.GetCacheKeyFromVirtualPath(VirtualPath virtualPath, Boolean& keyFromVPP) 
    w System.Web.Compilation.BuildManager.GetVPathBuildResultFromCacheInternal(VirtualPath virtualPath, Boolean ensureIsUpToDate) 
    w System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate) 
    w System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate) 
    w System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean throwIfNotFound) 
    w System.Web.Compilation.BuildManager.GetObjectFactory(String virtualPath, Boolean throwIfNotFound) 
    w System.Web.Mvc.BuildManagerWrapper.System.Web.Mvc.IBuildManager.FileExists(String virtualPath) 
    w System.Web.Mvc.BuildManagerViewEngine.FileExists(ControllerContext controllerContext, String virtualPath) 
    w System.Web.Mvc.VirtualPathProviderViewEngine.GetPathFromSpecificName(ControllerContext controllerContext, String name, String cacheKey, String[]& searchedLocations) 
    w System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext controllerContext, String[] locations, String[] areaLocations, String locationsPropertyName, String name, String controllerName, String cacheKeyPrefix, Boolean useCache, String[]& searchedLocations) 
    w System.Web.Mvc.VirtualPathProviderViewEngine.FindView(ControllerContext controllerContext, String viewName, String masterName, Boolean useCache) 
    w System.Web.Mvc.ViewEngineCollection.<>c__DisplayClassc.<FindView>b__b(IViewEngine e) 
    w System.Web.Mvc.ViewEngineCollection.Find(Func`2 lookup, Boolean trackSearchedPaths) 
    w System.Web.Mvc.ViewEngineCollection.Find(Func`2 cacheLocator, Func`2 locator) 
    w System.Web.Mvc.ViewEngineCollection.FindView(ControllerContext controllerContext, String viewName, String masterName) 
    w MvcApplication.Infrastructure.Services.MailingService.RenderEmailBody[T](String viewPath, T model, ControllerContext controllerContext, Boolean isParialView) w d:\MyProjects\CertyfikatyNoble\branches\Certyfikaty3\MvcApplication\Infrastructure\Services\MailingService.cs:wiersz 175 
    w MvcApplication.Tests.MailingServiceTests.ViewToStrngTest() w d:\MyProjects\CertyfikatyNoble\branches\Certyfikaty3\MvcApplication.Tests\MailingServiceTests.cs:wiersz 144 

renderowania kodu metody: metoda

public string RenderEmailBody<T>(string viewPath, T model, ControllerContext controllerContext, bool isParialView) 
{ 
    ViewEngineResult viewEngineResult = null; 
    if (isParialView == true) 
    { 
     viewEngineResult = ViewEngines.Engines.FindPartialView(controllerContext, viewPath); 
    } 
    else 
    { 
     viewEngineResult = ViewEngines.Engines.FindView(controllerContext, viewPath, null); 
    } 

    if (viewEngineResult == null) 
    { 
     throw new FileNotFoundException("Coukld not find view."); 
    } 

    var view = viewEngineResult.View; 
    controllerContext.Controller.ViewData.Model = model; 

    string result = null; 

    using (var sw = new StringWriter()) 
    { 
     var ctx = new ViewContext(controllerContext, view, 
            controllerContext.Controller.ViewData, 
            controllerContext.Controller.TempData, 
            sw); 
     view.Render(ctx, sw); 
     result = sw.ToString(); 
    } 

    return result; 
} 

A Test z kontekstu kontrolera makiety:

 Mock<HttpBrowserCapabilitiesBase> browserMock = new Mock<HttpBrowserCapabilitiesBase>(); 
     browserMock.Setup(m => m.IsMobileDevice).Returns(false); 

     Mock<HttpServerUtilityBase> httpServerUtilityBaseMock = new Mock<HttpServerUtilityBase>(MockBehavior.Strict); 

     Mock<HttpResponseBase> httpResponseMock = new Mock<HttpResponseBase>(MockBehavior.Strict); 
     httpResponseMock.Setup(m => m.Cookies).Returns(new HttpCookieCollection() { new HttpCookie("ResponseCookieTest") }); 

     Mock<HttpRequestBase> httpRequestMock = new Mock<HttpRequestBase>(MockBehavior.Strict); 
     httpRequestMock.Setup(m => m.UserHostAddress).Returns("127.0.0.1"); 
     httpRequestMock.Setup(m => m.Cookies).Returns(new HttpCookieCollection() { new HttpCookie("RequestCookieTest") }); 
     httpRequestMock.Setup(m => m.UserAgent).Returns("None"); 
     httpRequestMock.Setup(m => m.Browser).Returns(browserMock.Object); 
     httpRequestMock.Setup(m => m.ApplicationPath).Returns("/"); 
     httpRequestMock.Setup(m => m.AppRelativeCurrentExecutionFilePath).Returns("/"); 
     httpRequestMock.Setup(m => m.PathInfo).Returns(string.Empty); 
     httpRequestMock.Setup(m => m.Form).Returns(new NameValueCollection()); 
     httpRequestMock.Setup(m => m.QueryString).Returns(new NameValueCollection()); 

     Mock<HttpSessionStateBase> httpSessionStateMock = new Mock<HttpSessionStateBase>(MockBehavior.Strict); 
     httpSessionStateMock.Setup(m => m.SessionID).Returns(Guid.NewGuid().ToString()); 


     Mock<HttpContextBase> HttpContextMock = new Mock<HttpContextBase>(MockBehavior.Strict); 
     HttpContextMock.Setup(m => m.Request).Returns(httpRequestMock.Object); 
     HttpContextMock.Setup(m => m.Response).Returns(httpResponseMock.Object); 
     HttpContextMock.Setup(m => m.Server).Returns(httpServerUtilityBaseMock.Object); 
     HttpContextMock.Setup(m => m.Session).Returns(httpSessionStateMock.Object); 

     HttpContextMock.Setup(m => m.Items).Returns(new ListDictionary()); 

     RouteData routeData = new RouteData(); 
     routeData.Values.Add("controller", "someController"); 
     routeData.Values.Add("action", "index"); 

     Mock<ControllerContext> controllerContextMock = new Mock<ControllerContext>(MockBehavior.Strict); 
     controllerContextMock.Setup(m => m.HttpContext).Returns(HttpContextMock.Object); 
     controllerContextMock.Setup(m => m.RouteData).Returns(routeData); 
     controllerContextMock.Setup(m => m.Controller).Returns(new AccountController()); 

     SiteConfigurationService siteConfigurationService = SiteConfigurationService.Instance(); 
     siteConfigurationService.LoadConfig<SiteConfigurations>(this._siteConfigurationsRepository.GetDefaultConfig()); 

     MailingService service = new MailingService(controllerContextMock.Object, siteConfigurationService); 

     string result = service.RenderEmailBody<object>("/ViewToRenderToString.cshtml", new object(), controllerContextMock.Object, false); 

czytam HERE że przyczyną jest to, że _virtualPath i HttpRuntime.AppDomainAppVirtualPathString int System.Web.VirtualP athString ma wartość NULL.

Czy można ustawić je do testowania jednostkowego?

Dzięki z góry,

+0

Zajrzałem do tego dość obszernie przy poprzedniej okazji i jest to trudne. Zamiast tego można jak zwykle renderować treść wiadomości e-mail i odczytać ją przy użyciu WebRequest lub podobnego. Następnie wykonaj test integracji na wypadek, gdyby chcesz zobaczyć, jak renderuje. – JuhaKangas

+0

rzeczy, które zrobiłem, gdy próbowałem to zrobić bez odwoływania się do webrequestu: włącz dozwolony framework .net krokowy i/lub pobierz kod źródłowy mvc, dekompiluj zespół, który błędnie bezpośrednio. Nie sądzę, żebym to osiągnął, ale jestem BARDZO zainteresowany odpowiedzią – Maslow

Odpowiedz

0

Czy próbowałeś realizacji własnego VirtualPathProvider?

coś takiego:

public class CustomVirtualPathProvider : VirtualPathProvider 
    { 
     internal class CustomVirtualFile : ViewVirtualFile 
     { 
      public override bool IsDirectory 
      { 
       get 
       { 
        return base.IsDirectory; 
       } 
      } 
      public override string Name 
      { 
       get 
       { 
        return base.Name; 
       } 
      } 
      public override string ResourceKey 
      { 
       get 
       { 
        return base.ResourceKey; 
       } 
      } 
      public override System.IO.Stream Open() 
      { 
       return base.Open(); 
      } 
      public CustomVirtualFile(string path) 
       : base(path) 
      { 

      } 

     } 
     public override bool FileExists(string virtualPath) 
     { 
      return base.FileExists(virtualPath); 
     } 
     public override VirtualFile GetFile(string virtualPath) 
     { 
      return base.GetFile(virtualPath); 
     } 
     public override VirtualDirectory GetDirectory(string virtualDir) 
     { 
      return base.GetDirectory(virtualDir); 
     } 
     public override bool DirectoryExists(string virtualDir) 
     { 
      return base.DirectoryExists(virtualDir); 
     } 


    } 

Następnie w Global.asax

///register our custom virtual path provider factory. 
      HostingEnvironment.RegisterVirtualPathProvider(new CustomVirtualPathProvider()); 

Dzięki takiemu podejściu można uczynić widoki z każdego miejsca.