Use HostBuilder.UseUmbraco in same order for tests and running web app

This commit is contained in:
Paul Johnson
2020-12-17 12:18:28 +00:00
parent 79aa2e1cc2
commit a883df9d88
5 changed files with 29 additions and 23 deletions

View File

@@ -12,12 +12,7 @@ namespace Umbraco.Core.Composing
/// Adds CoreRuntime as HostedService
/// </summary>
/// <remarks>
/// <para>When running the site should be called before ConfigureWebDefaults.</para>
///
/// <para>
/// When testing should be called after ConfigureWebDefaults to ensure UseTestDatabase is called before CoreRuntime
/// starts or we initialize components with incorrect run level.
/// </para>
/// Should be called before ConfigureWebDefaults.
/// </remarks>
public static IHostBuilder UseUmbraco(this IHostBuilder builder)
{

View File

@@ -43,6 +43,7 @@ namespace Umbraco.Tests.Integration
var testHelper = new TestHelper();
var hostBuilder = new HostBuilder()
.UseUmbraco()
.ConfigureServices((hostContext, services) =>
{
var webHostEnvironment = testHelper.GetWebHostEnvironment();
@@ -68,8 +69,7 @@ namespace Umbraco.Tests.Integration
.Build();
services.AddRouting(); // LinkGenerator
})
.UseUmbraco();
});
var host = await hostBuilder.StartAsync();
var app = new ApplicationBuilder(host.Services);

View File

@@ -19,7 +19,6 @@ using Umbraco.Core.DependencyInjection;
using Umbraco.Web.Common.Controllers;
using Microsoft.Extensions.Hosting;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Web.BackOffice.Controllers;
namespace Umbraco.Tests.Integration.TestServerTest
@@ -35,7 +34,7 @@ namespace Umbraco.Tests.Integration.TestServerTest
InMemoryConfiguration["Umbraco:CMS:Hosting:Debug"] = "true";
// create new WebApplicationFactory specifying 'this' as the IStartup instance
var factory = new UmbracoWebApplicationFactory<UmbracoTestServerTestBase>(CreateHostBuilder);
var factory = new UmbracoWebApplicationFactory<UmbracoTestServerTestBase>(CreateHostBuilder, BeforeHostStart);
// additional host configuration for web server integration tests
Factory = factory.WithWebHostBuilder(builder =>
@@ -71,15 +70,11 @@ namespace Umbraco.Tests.Integration.TestServerTest
// call startup
builder.Configure(app =>
{
Services = app.ApplicationServices;
UseTestDatabase(app.ApplicationServices);
Configure(app);
});
}).UseEnvironment(Environments.Development);
builder.UseUmbraco(); // Ensures CoreRuntime.StartAsync is called, must be after ConfigureWebHost
return builder;
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Hosting;
@@ -8,16 +8,30 @@ namespace Umbraco.Tests.Integration.TestServerTest
public class UmbracoWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
private readonly Func<IHostBuilder> _createHostBuilder;
private readonly Action<IHost> _beforeStart;
/// <summary>
/// Constructor to create a new WebApplicationFactory
/// </summary>
/// <param name="createHostBuilder">Method to create the IHostBuilder</param>
public UmbracoWebApplicationFactory(Func<IHostBuilder> createHostBuilder)
/// <param name="beforeStart">Method to perform an action before IHost starts</param>
public UmbracoWebApplicationFactory(Func<IHostBuilder> createHostBuilder, Action<IHost> beforeStart = null)
{
_createHostBuilder = createHostBuilder;
_beforeStart = beforeStart;
}
protected override IHostBuilder CreateHostBuilder() => _createHostBuilder();
protected override IHost CreateHost(IHostBuilder builder)
{
IHost host = builder.Build();
_beforeStart?.Invoke(host);
host.Start();
return host;
}
}
}

View File

@@ -97,18 +97,22 @@ namespace Umbraco.Tests.Integration.Testing
public virtual void Setup()
{
InMemoryConfiguration[Constants.Configuration.ConfigGlobal + ":" + nameof(GlobalSettings.InstallEmptyDatabase)] = "true";
var hostBuilder = CreateHostBuilder()
.UseUmbraco(); // This ensures CoreRuntime.StartAsync will be called (however it's a mock if boot = false)
var hostBuilder = CreateHostBuilder();
IHost host = hostBuilder.Build();
Services = host.Services;
BeforeHostStart(host);
host.Start();
var app = new ApplicationBuilder(host.Services);
Configure(app);
}
protected void BeforeHostStart(IHost host)
{
Services = host.Services;
UseTestDatabase(Services);
}
#region Generic Host Builder and Runtime
private ILoggerFactory CreateLoggerFactory()
@@ -149,12 +153,12 @@ namespace Umbraco.Tests.Integration.Testing
public virtual IHostBuilder CreateHostBuilder()
{
var hostBuilder = Host.CreateDefaultBuilder()
.UseUmbraco()
// IMPORTANT: We Cannot use UseStartup, there's all sorts of threads about this with testing. Although this can work
// if you want to setup your tests this way, it is a bit annoying to do that as the WebApplicationFactory will
// create separate Host instances. So instead of UseStartup, we just call ConfigureServices/Configure ourselves,
// and in the case of the UmbracoTestServerTestBase it will use the ConfigureWebHost to Configure the IApplicationBuilder directly.
//.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(GetType()); })
.ConfigureAppConfiguration((context, configBuilder) =>
{
context.HostingEnvironment = TestHelper.GetWebHostEnvironment();
@@ -233,8 +237,6 @@ namespace Umbraco.Tests.Integration.Testing
public virtual void Configure(IApplicationBuilder app)
{
UseTestDatabase(app.ApplicationServices);
if (TestOptions.Boot)
{
Services.GetRequiredService<IBackOfficeSecurityFactory>().EnsureBackOfficeSecurity();