Skip to content

Commit b12c354

Browse files
committed
- Created an ITestServer abstraction to replace the TestServer dependency with from in the WebApplicationFactory.
- Updated the WebApplicationFactory to depend on the ITestServer abstraction
1 parent 9f3e60c commit b12c354

File tree

5 files changed

+64
-10
lines changed

5 files changed

+64
-10
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Net.Http;
5+
using Microsoft.AspNetCore.Hosting;
6+
using Microsoft.AspNetCore.Hosting.Server;
7+
8+
namespace Microsoft.AspNetCore.TestHost;
9+
10+
/// <summary>
11+
/// A contract for a test server implementation.
12+
/// </summary>
13+
public interface ITestServer : IServer
14+
{
15+
/// <summary>
16+
/// Gets the web host associated with the test server.
17+
/// </summary>
18+
IWebHost Host { get; }
19+
20+
/// <summary>
21+
/// Creates a new <see cref="HttpMessageHandler"/> for processing HTTP requests against the test server.
22+
/// </summary>
23+
/// <returns>A new <see cref="HttpMessageHandler"/> instance.</returns>
24+
HttpMessageHandler CreateHandler();
25+
26+
/// <summary>
27+
/// Creates a new <see cref="HttpClient"/> for processing HTTP requests against the test server.
28+
/// </summary>
29+
/// <returns></returns>
30+
HttpClient CreateClient();
31+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
#nullable enable
2+
Microsoft.AspNetCore.TestHost.ITestServer
3+
Microsoft.AspNetCore.TestHost.ITestServer.CreateClient() -> System.Net.Http.HttpClient!
4+
Microsoft.AspNetCore.TestHost.ITestServer.CreateHandler() -> System.Net.Http.HttpMessageHandler!
5+
Microsoft.AspNetCore.TestHost.ITestServer.Host.get -> Microsoft.AspNetCore.Hosting.IWebHost!

src/Hosting/TestHost/src/TestServer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.TestHost;
1414
/// <summary>
1515
/// An <see cref="IServer"/> implementation for executing tests.
1616
/// </summary>
17-
public class TestServer : IServer
17+
public class TestServer : ITestServer
1818
{
1919
private readonly IWebHost? _hostInstance;
2020
private bool _disposed;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
#nullable enable
2+
Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory<TEntryPoint>.Server.get -> Microsoft.AspNetCore.TestHost.TestServer?
3+
Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory<TEntryPoint>.TestServer.get -> Microsoft.AspNetCore.TestHost.ITestServer?

src/Mvc/Mvc.Testing/src/WebApplicationFactory.cs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,22 @@ namespace Microsoft.AspNetCore.Mvc.Testing;
2222
/// </summary>
2323
/// <typeparam name="TEntryPoint">A type in the entry point assembly of the application.
2424
/// Typically the Startup or Program classes can be used.</typeparam>
25+
/// <remarks>The default behavior of the <see cref="CreateServer(IWebHostBuilder)"/> implementation
26+
/// creates a new <see cref="TestHost.TestServer"/> instance as an in-memory server to utilize for testing.
27+
/// If the developers wants, they can override the <see cref="CreateServer(IWebHostBuilder)"/> method to return a customer <see cref="ITestServer"/> implementation,
28+
/// and provide an adapter over a real web server, if needed. If done so, the <see cref="CreateClient()"/> and similar methods will
29+
/// create <see cref="HttpClient"/> instances configured to interact with the provided test server instead.</remarks>
2530
public partial class WebApplicationFactory<TEntryPoint> : IDisposable, IAsyncDisposable where TEntryPoint : class
2631
{
2732
private bool _disposed;
2833
private bool _disposedAsync;
29-
private TestServer? _server;
34+
private ITestServer? _server;
3035
private IHost? _host;
3136
private Action<IWebHostBuilder> _configuration;
3237
private readonly List<HttpClient> _clients = new();
3338
private readonly List<WebApplicationFactory<TEntryPoint>> _derivedFactories = new();
3439

40+
3541
/// <summary>
3642
/// <para>
3743
/// Creates an instance of <see cref="WebApplicationFactory{TEntryPoint}"/>. This factory can be used to
@@ -71,12 +77,24 @@ public WebApplicationFactory()
7177
/// <summary>
7278
/// Gets the <see cref="TestServer"/> created by this <see cref="WebApplicationFactory{TEntryPoint}"/>.
7379
/// </summary>
74-
public TestServer Server
80+
[Obsolete("This property is obsolete. Consider utilizing the TestServer property instead.")]
81+
public TestServer? Server
82+
{
83+
get
84+
{
85+
return TestServer as TestServer;
86+
}
87+
}
88+
89+
/// <summary>
90+
/// Gets the <see cref="ITestServer"/> instance created by the underyling <see cref="CreateServer(IWebHostBuilder)"/> call.
91+
/// </summary>
92+
public ITestServer? TestServer
7593
{
7694
get
7795
{
7896
EnsureServer();
79-
return _server;
97+
return _server!;
8098
}
8199
}
82100

@@ -136,7 +154,6 @@ internal virtual WebApplicationFactory<TEntryPoint> WithWebHostBuilderCore(Actio
136154
return factory;
137155
}
138156

139-
[MemberNotNull(nameof(_server))]
140157
private void EnsureServer()
141158
{
142159
if (_server != null)
@@ -211,7 +228,7 @@ private void ConfigureHostBuilder(IHostBuilder hostBuilder)
211228
webHostBuilder.UseTestServer();
212229
});
213230
_host = CreateHost(hostBuilder);
214-
_server = (TestServer)_host.Services.GetRequiredService<IServer>();
231+
_server = _host.Services.GetRequiredService<IServer>() as ITestServer;
215232
}
216233

217234
private void SetContentRoot(IWebHostBuilder builder)
@@ -426,7 +443,7 @@ private static void EnsureDepsFile()
426443
/// <param name="builder">The <see cref="IWebHostBuilder"/> used to
427444
/// create the server.</param>
428445
/// <returns>The <see cref="TestServer"/> with the bootstrapped application.</returns>
429-
protected virtual TestServer CreateServer(IWebHostBuilder builder) => new(builder);
446+
protected virtual ITestServer CreateServer(IWebHostBuilder builder) => new TestServer(builder);
430447

431448
/// <summary>
432449
/// Creates the <see cref="IHost"/> with the bootstrapped application in <paramref name="builder"/>.
@@ -606,7 +623,7 @@ public virtual async ValueTask DisposeAsync()
606623

607624
private sealed class DelegatedWebApplicationFactory : WebApplicationFactory<TEntryPoint>
608625
{
609-
private readonly Func<IWebHostBuilder, TestServer> _createServer;
626+
private readonly Func<IWebHostBuilder, ITestServer> _createServer;
610627
private readonly Func<IHostBuilder, IHost> _createHost;
611628
private readonly Func<IWebHostBuilder?> _createWebHostBuilder;
612629
private readonly Func<IHostBuilder?> _createHostBuilder;
@@ -615,7 +632,7 @@ private sealed class DelegatedWebApplicationFactory : WebApplicationFactory<TEnt
615632

616633
public DelegatedWebApplicationFactory(
617634
WebApplicationFactoryClientOptions options,
618-
Func<IWebHostBuilder, TestServer> createServer,
635+
Func<IWebHostBuilder, ITestServer> createServer,
619636
Func<IHostBuilder, IHost> createHost,
620637
Func<IWebHostBuilder?> createWebHostBuilder,
621638
Func<IHostBuilder?> createHostBuilder,
@@ -633,7 +650,7 @@ public DelegatedWebApplicationFactory(
633650
_configuration = configureWebHost;
634651
}
635652

636-
protected override TestServer CreateServer(IWebHostBuilder builder) => _createServer(builder);
653+
protected override ITestServer CreateServer(IWebHostBuilder builder) => _createServer(builder);
637654

638655
protected override IHost CreateHost(IHostBuilder builder) => _createHost(builder);
639656

0 commit comments

Comments
 (0)