Skip to content

Commit f3326d7

Browse files
Use UseKestrel() with WebApplicationFactory<T>
Use the new `UseKestrel()` method for `WebApplicationFactory<T>` to remove the customisation needed to host the application on an HTTP port.
1 parent a98077c commit f3326d7

File tree

1 file changed

+12
-91
lines changed

1 file changed

+12
-91
lines changed
Lines changed: 12 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,34 @@
11
// Copyright (c) Martin Costello, 2021. All rights reserved.
22
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
33

4+
using System.Net;
45
using System.Security.Cryptography.X509Certificates;
56
using Microsoft.AspNetCore.Hosting;
6-
using Microsoft.AspNetCore.Hosting.Server;
7-
using Microsoft.AspNetCore.Hosting.Server.Features;
8-
using Microsoft.Extensions.DependencyInjection;
9-
using Microsoft.Extensions.Hosting;
107

118
namespace TodoApp;
129

1310
/// <summary>
14-
/// A test server fixture that hosts the application on an HTTP port so
11+
/// A test server fixture that hosts the application on an HTTPS port so
1512
/// that the application can be accessed through a browser for UI tests.
1613
/// </summary>
1714
public sealed class HttpServerFixture : TodoAppFixture
1815
{
19-
private bool _disposed;
20-
private IHost? _host;
21-
22-
public string ServerAddress
16+
public HttpServerFixture()
2317
{
24-
get
25-
{
26-
EnsureServer();
27-
return ClientOptions.BaseAddress.ToString();
28-
}
18+
// Configure the address for the server to listen on for HTTPS
19+
// requests on a dynamic port. with a self-signed TLS certificate.
20+
UseKestrel(
21+
(server) => server.Listen(
22+
IPAddress.Loopback, 0, (listener) => listener.UseHttps(
23+
(https) => https.ServerCertificate = X509CertificateLoader.LoadPkcs12FromFile("localhost-dev.pfx", "Pa55w0rd!"))));
2924
}
3025

31-
public override IServiceProvider Services
26+
public string ServerAddress
3227
{
3328
get
3429
{
35-
EnsureServer();
36-
return _host!.Services!;
37-
}
38-
}
39-
40-
protected override void ConfigureWebHost(IWebHostBuilder builder)
41-
{
42-
base.ConfigureWebHost(builder);
43-
44-
// Configure a self-signed TLS certificate for HTTPS
45-
builder.ConfigureKestrel(
46-
serverOptions => serverOptions.ConfigureHttpsDefaults(
47-
httpsOptions => httpsOptions.ServerCertificate = X509CertificateLoader.LoadPkcs12FromFile("localhost-dev.pfx", "Pa55w0rd!")));
48-
49-
// Configure the server address for the server to
50-
// listen on for HTTPS requests on a dynamic port.
51-
builder.UseUrls("https://127.0.0.1:0");
52-
}
53-
54-
protected override IHost CreateHost(IHostBuilder builder)
55-
{
56-
// Create the host for TestServer now before we
57-
// modify the builder to use Kestrel instead.
58-
var testHost = builder.Build();
59-
60-
// Modify the host builder to use Kestrel instead
61-
// of TestServer so we can listen on a real address.
62-
builder.ConfigureWebHost(webHostBuilder => webHostBuilder.UseKestrel());
63-
64-
// Create and start the Kestrel server before the test server,
65-
// otherwise due to the way the deferred host builder works
66-
// for minimal hosting, the server will not get "initialized
67-
// enough" for the address it is listening on to be available.
68-
// See https://github.com/dotnet/aspnetcore/issues/33846.
69-
_host = builder.Build();
70-
_host.Start();
71-
72-
// Extract the selected dynamic port out of the Kestrel server
73-
// and assign it onto the client options for convenience so it
74-
// "just works" as otherwise it'll be the default http://localhost
75-
// URL, which won't route to the Kestrel-hosted HTTP server.
76-
var server = _host.Services.GetRequiredService<IServer>();
77-
var addresses = server.Features.Get<IServerAddressesFeature>();
78-
79-
ClientOptions.BaseAddress = addresses!.Addresses
80-
.Select(x => new Uri(x))
81-
.Last();
82-
83-
// Return the host that uses TestServer, rather than the real one.
84-
// Otherwise the internals will complain about the host's server
85-
// not being an instance of the concrete type TestServer.
86-
// See https://github.com/dotnet/aspnetcore/pull/34702.
87-
return testHost;
88-
}
89-
90-
protected override void Dispose(bool disposing)
91-
{
92-
base.Dispose(disposing);
93-
94-
if (!_disposed)
95-
{
96-
if (disposing)
97-
{
98-
_host?.Dispose();
99-
}
100-
101-
_disposed = true;
102-
}
103-
}
104-
105-
private void EnsureServer()
106-
{
107-
if (_host is null)
108-
{
109-
// This forces WebApplicationFactory to bootstrap the server
110-
using var _ = CreateDefaultClient();
30+
StartServer();
31+
return ClientOptions.BaseAddress.ToString();
11132
}
11233
}
11334
}

0 commit comments

Comments
 (0)