WebApplicationFactory throws error that contentRootPath does not exist in ASP.NET Core integration test










1














I have a ASP.NET Core project with some simple Razor pages and a Web API controller.



I'm using Clean Architecture as a starting point. I've renamed the project names, removed the MVC stuff and added some of my own code. Everything runs and works.



However, the integration tests throw the following error when calling factory.CreateClient():



Test Name: ToDo.Tests.Integration.Web.HomeControllerIndexShould.ReturnViewWithCorrectMessage
Test FullName: ToDo.Tests.Integration.Web.HomeControllerIndexShould.ReturnViewWithCorrectMessage
Test Source: C:SourceUtopiatestsToDo.TestsIntegrationWebHomeControllerIndexShould.cs : line 18
Test Outcome: Failed
Test Duration: 0:00:00,001

Result StackTrace:
at Microsoft.AspNetCore.Hosting.Internal.HostingEnvironmentExtensions.Initialize(IHostingEnvironment hostingEnvironment, String contentRootPath, WebHostOptions options)
at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
at Microsoft.AspNetCore.TestHost.TestServer..ctor(IWebHostBuilder builder, IFeatureCollection featureCollection)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateServer(IWebHostBuilder builder)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.EnsureServer()
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler handlers)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
at ToDo.Tests.Integration.Web.HomeControllerIndexShould..ctor(CustomWebApplicationFactory`1 factory) in C:SourceUtopiatestsToDo.TestsIntegrationWebHomeControllerIndexShould.cs:line 14
Result Message:
System.ArgumentException : The content root 'C:SourceUtopiaToDo.Web' does not exist.
Parameter name: contentRootPath


I've tried configuring the custom WebApplicationFactory by using builder.UseContentRoot and builder.UseSolutionRelativeContentRoot but it keeps throwing the same error no matter what values I use for the ContentRoot methods.



I don't know why my tests are failing while the one in the Clean Architecture sample are working. I also don't know how to fix it.



Any pointers are highly appreciated!










share|improve this question


























    1














    I have a ASP.NET Core project with some simple Razor pages and a Web API controller.



    I'm using Clean Architecture as a starting point. I've renamed the project names, removed the MVC stuff and added some of my own code. Everything runs and works.



    However, the integration tests throw the following error when calling factory.CreateClient():



    Test Name: ToDo.Tests.Integration.Web.HomeControllerIndexShould.ReturnViewWithCorrectMessage
    Test FullName: ToDo.Tests.Integration.Web.HomeControllerIndexShould.ReturnViewWithCorrectMessage
    Test Source: C:SourceUtopiatestsToDo.TestsIntegrationWebHomeControllerIndexShould.cs : line 18
    Test Outcome: Failed
    Test Duration: 0:00:00,001

    Result StackTrace:
    at Microsoft.AspNetCore.Hosting.Internal.HostingEnvironmentExtensions.Initialize(IHostingEnvironment hostingEnvironment, String contentRootPath, WebHostOptions options)
    at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
    at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
    at Microsoft.AspNetCore.TestHost.TestServer..ctor(IWebHostBuilder builder, IFeatureCollection featureCollection)
    at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateServer(IWebHostBuilder builder)
    at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.EnsureServer()
    at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler handlers)
    at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
    at ToDo.Tests.Integration.Web.HomeControllerIndexShould..ctor(CustomWebApplicationFactory`1 factory) in C:SourceUtopiatestsToDo.TestsIntegrationWebHomeControllerIndexShould.cs:line 14
    Result Message:
    System.ArgumentException : The content root 'C:SourceUtopiaToDo.Web' does not exist.
    Parameter name: contentRootPath


    I've tried configuring the custom WebApplicationFactory by using builder.UseContentRoot and builder.UseSolutionRelativeContentRoot but it keeps throwing the same error no matter what values I use for the ContentRoot methods.



    I don't know why my tests are failing while the one in the Clean Architecture sample are working. I also don't know how to fix it.



    Any pointers are highly appreciated!










    share|improve this question
























      1












      1








      1


      1





      I have a ASP.NET Core project with some simple Razor pages and a Web API controller.



      I'm using Clean Architecture as a starting point. I've renamed the project names, removed the MVC stuff and added some of my own code. Everything runs and works.



      However, the integration tests throw the following error when calling factory.CreateClient():



      Test Name: ToDo.Tests.Integration.Web.HomeControllerIndexShould.ReturnViewWithCorrectMessage
      Test FullName: ToDo.Tests.Integration.Web.HomeControllerIndexShould.ReturnViewWithCorrectMessage
      Test Source: C:SourceUtopiatestsToDo.TestsIntegrationWebHomeControllerIndexShould.cs : line 18
      Test Outcome: Failed
      Test Duration: 0:00:00,001

      Result StackTrace:
      at Microsoft.AspNetCore.Hosting.Internal.HostingEnvironmentExtensions.Initialize(IHostingEnvironment hostingEnvironment, String contentRootPath, WebHostOptions options)
      at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
      at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
      at Microsoft.AspNetCore.TestHost.TestServer..ctor(IWebHostBuilder builder, IFeatureCollection featureCollection)
      at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateServer(IWebHostBuilder builder)
      at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.EnsureServer()
      at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler handlers)
      at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
      at ToDo.Tests.Integration.Web.HomeControllerIndexShould..ctor(CustomWebApplicationFactory`1 factory) in C:SourceUtopiatestsToDo.TestsIntegrationWebHomeControllerIndexShould.cs:line 14
      Result Message:
      System.ArgumentException : The content root 'C:SourceUtopiaToDo.Web' does not exist.
      Parameter name: contentRootPath


      I've tried configuring the custom WebApplicationFactory by using builder.UseContentRoot and builder.UseSolutionRelativeContentRoot but it keeps throwing the same error no matter what values I use for the ContentRoot methods.



      I don't know why my tests are failing while the one in the Clean Architecture sample are working. I also don't know how to fix it.



      Any pointers are highly appreciated!










      share|improve this question













      I have a ASP.NET Core project with some simple Razor pages and a Web API controller.



      I'm using Clean Architecture as a starting point. I've renamed the project names, removed the MVC stuff and added some of my own code. Everything runs and works.



      However, the integration tests throw the following error when calling factory.CreateClient():



      Test Name: ToDo.Tests.Integration.Web.HomeControllerIndexShould.ReturnViewWithCorrectMessage
      Test FullName: ToDo.Tests.Integration.Web.HomeControllerIndexShould.ReturnViewWithCorrectMessage
      Test Source: C:SourceUtopiatestsToDo.TestsIntegrationWebHomeControllerIndexShould.cs : line 18
      Test Outcome: Failed
      Test Duration: 0:00:00,001

      Result StackTrace:
      at Microsoft.AspNetCore.Hosting.Internal.HostingEnvironmentExtensions.Initialize(IHostingEnvironment hostingEnvironment, String contentRootPath, WebHostOptions options)
      at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
      at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
      at Microsoft.AspNetCore.TestHost.TestServer..ctor(IWebHostBuilder builder, IFeatureCollection featureCollection)
      at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateServer(IWebHostBuilder builder)
      at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.EnsureServer()
      at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler handlers)
      at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
      at ToDo.Tests.Integration.Web.HomeControllerIndexShould..ctor(CustomWebApplicationFactory`1 factory) in C:SourceUtopiatestsToDo.TestsIntegrationWebHomeControllerIndexShould.cs:line 14
      Result Message:
      System.ArgumentException : The content root 'C:SourceUtopiaToDo.Web' does not exist.
      Parameter name: contentRootPath


      I've tried configuring the custom WebApplicationFactory by using builder.UseContentRoot and builder.UseSolutionRelativeContentRoot but it keeps throwing the same error no matter what values I use for the ContentRoot methods.



      I don't know why my tests are failing while the one in the Clean Architecture sample are working. I also don't know how to fix it.



      Any pointers are highly appreciated!







      c# asp.net-core integration-testing






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 12 at 20:44









      Wouter de Kort

      29.9k85791




      29.9k85791






















          2 Answers
          2






          active

          oldest

          votes


















          1














          I'm not entirely sure what you're talking about, but you shouldn't be configuring stuff like this in a test project, in the first place. Instead, you should create a class like TestStartup and inherit from the SUT's Startup class. In the SUT's Startup class, you should factor out things like your DB setup and such into virtual private methods, which you can then override on TestStartup. For example, you could create a method like:



          private virtual void ConfigureDatabase(IServiceCollection services)

          services.AddDbContext<MyContext>(o =>
          o.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));



          Then in your TestStartup, you'd add something like:



          private override void ConfigureDatabase(IServiceCollection services)

          var databaseName = Guid.NewGuid().ToString();
          services.AddDbContext<MyContext>(o =>
          o.UseInMemoryDatabase(databaseName));



          Then, when setting up your factory for testing, you tell it to use your TestStartup:



          var client = factory.WithWebHostBuilder(b => b.UseStartup<TestStartup>()).CreateClient();


          Or, you can create you own custom WebApplicationFactory and set it there:



          public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<RazorPagesProject.Startup>

          protected override void ConfigureWebHost(IWebHostBuilder builder)

          builder.UseStartup<TestStartup>();




          Just bear in mind that the TStartup generic type param is for getting the entry point assembly, so you'd still put Startup there.



          The main point of this is that you don't need to repeat all your startup configuration, and then remember to keep in sync. Your test client will use the exact same startup config your actual apps uses, except for a few keep replacements like using an in-memory database.






          share|improve this answer




















          • Thanks for the suggestion but after trying it I'm still getting the same error that contentRootPath isn't set.
            – Wouter de Kort
            Nov 17 at 14:15


















          0














          This method worked for me



           var client = _factory
          .WithWebHostBuilder(builder => builder.UseSolutionRelativeContentRoot("relative/path/of/project/under/test"))
          .CreateClient();


          See How the test infrastructure infers the app content root path for more information.






          share|improve this answer




















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53269815%2fwebapplicationfactory-throws-error-that-contentrootpath-does-not-exist-in-asp-ne%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            I'm not entirely sure what you're talking about, but you shouldn't be configuring stuff like this in a test project, in the first place. Instead, you should create a class like TestStartup and inherit from the SUT's Startup class. In the SUT's Startup class, you should factor out things like your DB setup and such into virtual private methods, which you can then override on TestStartup. For example, you could create a method like:



            private virtual void ConfigureDatabase(IServiceCollection services)

            services.AddDbContext<MyContext>(o =>
            o.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));



            Then in your TestStartup, you'd add something like:



            private override void ConfigureDatabase(IServiceCollection services)

            var databaseName = Guid.NewGuid().ToString();
            services.AddDbContext<MyContext>(o =>
            o.UseInMemoryDatabase(databaseName));



            Then, when setting up your factory for testing, you tell it to use your TestStartup:



            var client = factory.WithWebHostBuilder(b => b.UseStartup<TestStartup>()).CreateClient();


            Or, you can create you own custom WebApplicationFactory and set it there:



            public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<RazorPagesProject.Startup>

            protected override void ConfigureWebHost(IWebHostBuilder builder)

            builder.UseStartup<TestStartup>();




            Just bear in mind that the TStartup generic type param is for getting the entry point assembly, so you'd still put Startup there.



            The main point of this is that you don't need to repeat all your startup configuration, and then remember to keep in sync. Your test client will use the exact same startup config your actual apps uses, except for a few keep replacements like using an in-memory database.






            share|improve this answer




















            • Thanks for the suggestion but after trying it I'm still getting the same error that contentRootPath isn't set.
              – Wouter de Kort
              Nov 17 at 14:15















            1














            I'm not entirely sure what you're talking about, but you shouldn't be configuring stuff like this in a test project, in the first place. Instead, you should create a class like TestStartup and inherit from the SUT's Startup class. In the SUT's Startup class, you should factor out things like your DB setup and such into virtual private methods, which you can then override on TestStartup. For example, you could create a method like:



            private virtual void ConfigureDatabase(IServiceCollection services)

            services.AddDbContext<MyContext>(o =>
            o.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));



            Then in your TestStartup, you'd add something like:



            private override void ConfigureDatabase(IServiceCollection services)

            var databaseName = Guid.NewGuid().ToString();
            services.AddDbContext<MyContext>(o =>
            o.UseInMemoryDatabase(databaseName));



            Then, when setting up your factory for testing, you tell it to use your TestStartup:



            var client = factory.WithWebHostBuilder(b => b.UseStartup<TestStartup>()).CreateClient();


            Or, you can create you own custom WebApplicationFactory and set it there:



            public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<RazorPagesProject.Startup>

            protected override void ConfigureWebHost(IWebHostBuilder builder)

            builder.UseStartup<TestStartup>();




            Just bear in mind that the TStartup generic type param is for getting the entry point assembly, so you'd still put Startup there.



            The main point of this is that you don't need to repeat all your startup configuration, and then remember to keep in sync. Your test client will use the exact same startup config your actual apps uses, except for a few keep replacements like using an in-memory database.






            share|improve this answer




















            • Thanks for the suggestion but after trying it I'm still getting the same error that contentRootPath isn't set.
              – Wouter de Kort
              Nov 17 at 14:15













            1












            1








            1






            I'm not entirely sure what you're talking about, but you shouldn't be configuring stuff like this in a test project, in the first place. Instead, you should create a class like TestStartup and inherit from the SUT's Startup class. In the SUT's Startup class, you should factor out things like your DB setup and such into virtual private methods, which you can then override on TestStartup. For example, you could create a method like:



            private virtual void ConfigureDatabase(IServiceCollection services)

            services.AddDbContext<MyContext>(o =>
            o.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));



            Then in your TestStartup, you'd add something like:



            private override void ConfigureDatabase(IServiceCollection services)

            var databaseName = Guid.NewGuid().ToString();
            services.AddDbContext<MyContext>(o =>
            o.UseInMemoryDatabase(databaseName));



            Then, when setting up your factory for testing, you tell it to use your TestStartup:



            var client = factory.WithWebHostBuilder(b => b.UseStartup<TestStartup>()).CreateClient();


            Or, you can create you own custom WebApplicationFactory and set it there:



            public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<RazorPagesProject.Startup>

            protected override void ConfigureWebHost(IWebHostBuilder builder)

            builder.UseStartup<TestStartup>();




            Just bear in mind that the TStartup generic type param is for getting the entry point assembly, so you'd still put Startup there.



            The main point of this is that you don't need to repeat all your startup configuration, and then remember to keep in sync. Your test client will use the exact same startup config your actual apps uses, except for a few keep replacements like using an in-memory database.






            share|improve this answer












            I'm not entirely sure what you're talking about, but you shouldn't be configuring stuff like this in a test project, in the first place. Instead, you should create a class like TestStartup and inherit from the SUT's Startup class. In the SUT's Startup class, you should factor out things like your DB setup and such into virtual private methods, which you can then override on TestStartup. For example, you could create a method like:



            private virtual void ConfigureDatabase(IServiceCollection services)

            services.AddDbContext<MyContext>(o =>
            o.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));



            Then in your TestStartup, you'd add something like:



            private override void ConfigureDatabase(IServiceCollection services)

            var databaseName = Guid.NewGuid().ToString();
            services.AddDbContext<MyContext>(o =>
            o.UseInMemoryDatabase(databaseName));



            Then, when setting up your factory for testing, you tell it to use your TestStartup:



            var client = factory.WithWebHostBuilder(b => b.UseStartup<TestStartup>()).CreateClient();


            Or, you can create you own custom WebApplicationFactory and set it there:



            public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<RazorPagesProject.Startup>

            protected override void ConfigureWebHost(IWebHostBuilder builder)

            builder.UseStartup<TestStartup>();




            Just bear in mind that the TStartup generic type param is for getting the entry point assembly, so you'd still put Startup there.



            The main point of this is that you don't need to repeat all your startup configuration, and then remember to keep in sync. Your test client will use the exact same startup config your actual apps uses, except for a few keep replacements like using an in-memory database.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 13 at 14:44









            Chris Pratt

            151k20233298




            151k20233298











            • Thanks for the suggestion but after trying it I'm still getting the same error that contentRootPath isn't set.
              – Wouter de Kort
              Nov 17 at 14:15
















            • Thanks for the suggestion but after trying it I'm still getting the same error that contentRootPath isn't set.
              – Wouter de Kort
              Nov 17 at 14:15















            Thanks for the suggestion but after trying it I'm still getting the same error that contentRootPath isn't set.
            – Wouter de Kort
            Nov 17 at 14:15




            Thanks for the suggestion but after trying it I'm still getting the same error that contentRootPath isn't set.
            – Wouter de Kort
            Nov 17 at 14:15













            0














            This method worked for me



             var client = _factory
            .WithWebHostBuilder(builder => builder.UseSolutionRelativeContentRoot("relative/path/of/project/under/test"))
            .CreateClient();


            See How the test infrastructure infers the app content root path for more information.






            share|improve this answer

























              0














              This method worked for me



               var client = _factory
              .WithWebHostBuilder(builder => builder.UseSolutionRelativeContentRoot("relative/path/of/project/under/test"))
              .CreateClient();


              See How the test infrastructure infers the app content root path for more information.






              share|improve this answer























                0












                0








                0






                This method worked for me



                 var client = _factory
                .WithWebHostBuilder(builder => builder.UseSolutionRelativeContentRoot("relative/path/of/project/under/test"))
                .CreateClient();


                See How the test infrastructure infers the app content root path for more information.






                share|improve this answer












                This method worked for me



                 var client = _factory
                .WithWebHostBuilder(builder => builder.UseSolutionRelativeContentRoot("relative/path/of/project/under/test"))
                .CreateClient();


                See How the test infrastructure infers the app content root path for more information.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Dec 20 at 19:17









                Kit

                8,70423168




                8,70423168



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53269815%2fwebapplicationfactory-throws-error-that-contentrootpath-does-not-exist-in-asp-ne%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Top Tejano songwriter Luis Silva dead of heart attack at 64

                    ReactJS Fetched API data displays live - need Data displayed static

                    政党