Unit testing method that converts an MVC view to a string using the view.render method

I wrote a method that converts an MVC representation to a string and a testing method to check if it returns a string.

Of course, it works with the Web, but when I run the test in NUnit, it throws a NullReferenceException in System.Web when the method tries to call View.Render.

Here is the 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) wd:\MyProjects\CertyfikatyNoble\branches\Certyfikaty3\MvcApplication\Infrastructure\Services\MailingService.cs:wiersz 175 w MvcApplication.Tests.MailingServiceTests.ViewToStrngTest() wd:\MyProjects\CertyfikatyNoble\branches\Certyfikaty3\MvcApplication.Tests\MailingServiceTests.cs:wiersz 144 

Render Method Code:

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

And the verification method using the controller context:

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

I read HERE that the reason is that _virtualPath and HttpRuntime.AppDomainAppVirtualPathString int System.Web.VirtualPathString is NULL.

So is it possible to install them for unit testing?

Thanks in advance,

+6
source share
1 answer

Have you tried to implement your own VirtualPathProvider?

Something like that:

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

Then at Global.asax

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

With this approach, you can visualize views from anywhere.

0
source

Source: https://habr.com/ru/post/947557/


All Articles