Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

TestServer against MVC application can't find Razor Views. #3410

Closed
Bartmax opened this issue Oct 24, 2015 · 8 comments
Closed

TestServer against MVC application can't find Razor Views. #3410

Bartmax opened this issue Oct 24, 2015 · 8 comments

Comments

@Bartmax
Copy link

Bartmax commented Oct 24, 2015

As of right now, when you use TestServer on a Test project against an MVC application with Razor Views those are not found because ApplicationBasePath is the Test project one and not the MVC.

The solution is to change the ApplicationBasePath of the Test project to the MVC Application.

Changing the base path is not a straightforward thing to do, in terms that for every test project that needs this, one must implement IApplicationEnvironment and hook into the TestServer somehow.

I created a package at https://github.com/Bartmax/TestServerMvcHelper which hooks into WebHostingBuilder and does exactly that with one practical convention of where to look for the Application.

var builder = TestServer.CreateBuilder();
builder.UseApplicationPath("YourMvcApplication");
var server = new TestServer(builder);

I wanted to start a discussion to see if there's interest on the team for this (or similar) feature, as I think this should be provided/baked into the framework, with a maybe smarter way for application basepath discovery.

@pranavkm
Copy link
Contributor

Have you had a look at our functional tests and specifically MvcTestFixture (https://github.com/aspnet/Mvc/blob/dev/test/Microsoft.AspNet.Mvc.FunctionalTests/MvcTestFixture.cs)? The pattern works pretty well for our functional tests: https://github.com/aspnet/Mvc/blob/dev/test/Microsoft.AspNet.Mvc.FunctionalTests/ActionResultTests.cs#L15-L17.

@Bartmax
Copy link
Author

Bartmax commented Oct 24, 2015

@pranavkm yes, it's pretty good. I used it to understand how it works. Wouldn't be good to have something like that out of the box?

@rynowak
Copy link
Member

rynowak commented Oct 25, 2015

@Bartmax to a certain extent I agree, I think there's some things MVC requires that we won't put in the 'testserver' box.

Setting up the base path is something we might want to consider.

@Bartmax
Copy link
Author

Bartmax commented Oct 26, 2015

Sure, just let me know if you want me to help or contribute in any way.

@pranavkm
Copy link
Contributor

This is likely a dup of #6233

@rynowak
Copy link
Member

rynowak commented Jul 14, 2017

We're shipping a package in 2.0.0 that will address all of these issues. See: https://github.com/aspnet/Mvc/tree/dev/src/Microsoft.AspNetCore.Mvc.Testing

@rynowak rynowak closed this as completed Jul 14, 2017
@rynowak rynowak modified the milestones: 2.0.0, 2.1.0 Jul 14, 2017
@riezebosch
Copy link

riezebosch commented Aug 15, 2017

@rynowak Is it correct that the package is not available on nuget?!

https://www.nuget.org/packages?q=microsoft.aspnetcore.mvc.testing:

Search for microsoft.aspnetcore.mvc.testing returned 0 packages

Because it exists on the myget feed.

It is also mentioned in the release notes but I cannot find the assembly on the official channels.

@MookieFumi
Copy link

MookieFumi commented Jan 2, 2018

I'm trying to test an action thats return a Razor View and I'm experiencing some troubles because always is returning a 404. If I check the stacktrace the exception is "An unhandled exception has occurred: The view 'About' was not found".

I'm checking here that is going to be released in 2.1.0 version.

The view exists in the folder.
image

This my test code.

public class StringLocalizerTest
    {
        private readonly TestServer _server;
        private readonly HttpClient _client;

        public StringLocalizerTest()
        {
            var webHostBuilder = new WebHostBuilder()
                .UseStartup<Startup>();
            _server = new TestServer(webHostBuilder);
            _client = _server.CreateClient();
        }

        [Fact]
        public async Task Any_Test()
        {
            var response = await _client.GetAsync("/about");
            var content = await response.Content.ReadAsStringAsync();
        }
    }

This is my controller code.

    public class HomeController : Controller
    {
        // GET home/index
        [HttpGet]
        public IActionResult Index()
        {
            return View();
        }

        // GET home/about
        [HttpGet("about")]
        public IActionResult About()
        {
            return View();
        }

    }

This is the stacktrace.

Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ViewResultExecutor:Error: The view 'About' was not found. Searched locations: /Features/Home/About.cshtml, /Features/Home/Views/About.cshtml, /Features//Home/About.cshtml, /Features//Home/Views/About.cshtml, /Features//Shared/About.cshtml, /Features/Shared/About.cshtml, /Views/Shared/About.cshtml
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action MyWebApi.Features.Home.HomeController.About (MyWebApi) in 241.2277ms
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll
Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware:Error: An unhandled exception has occurred: The view 'About' was not found. The following locations were searched:
/Features/Home/About.cshtml
/Features/Home/Views/About.cshtml
/Features//Home/About.cshtml
/Features//Home/Views/About.cshtml
/Features//Shared/About.cshtml
/Features/Shared/About.cshtml
/Views/Shared/About.cshtml

System.InvalidOperationException: The view 'About' was not found. The following locations were searched:
/Features/Home/About.cshtml
/Features/Home/Views/About.cshtml
/Features//Home/About.cshtml
/Features//Home/Views/About.cshtml
/Features//Shared/About.cshtml
/Features/Shared/About.cshtml
/Views/Shared/About.cshtml
   at Microsoft.AspNetCore.Mvc.ViewEngines.ViewEngineResult.EnsureSuccessful(IEnumerable`1 originalLocations)
   at Microsoft.AspNetCore.Mvc.ViewResult.<ExecuteResultAsync>d__26.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeResultAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeNextResultFilterAsync>d__24.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeFilterPipelineAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeAsync>d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MyWebApi.Infrastructure.Middlewares.RequestResponseLoggingMiddleware.<Invoke>d__3.MoveNext() in C:\temp\MyNetCoreWebApi\MyWebApi\Infrastructure\Middlewares\RequestResponseLoggingMiddleware.cs:line 26
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>d__6.MoveNext()
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 407.0142ms 404 

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants