From 22777537695ab3afeaecfa676d2d165036c5d411 Mon Sep 17 00:00:00 2001 From: Fraser McLean Date: Thu, 29 May 2025 10:39:51 +0800 Subject: [PATCH 1/4] Add AppHost tests project --- backend/RateMyPet.slnx | 1 + .../tests/AppHost.Tests/AppHost.Tests.csproj | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 backend/tests/AppHost.Tests/AppHost.Tests.csproj diff --git a/backend/RateMyPet.slnx b/backend/RateMyPet.slnx index 194cdb80..f792547e 100644 --- a/backend/RateMyPet.slnx +++ b/backend/RateMyPet.slnx @@ -9,6 +9,7 @@ + diff --git a/backend/tests/AppHost.Tests/AppHost.Tests.csproj b/backend/tests/AppHost.Tests/AppHost.Tests.csproj new file mode 100644 index 00000000..ca15cc9c --- /dev/null +++ b/backend/tests/AppHost.Tests/AppHost.Tests.csproj @@ -0,0 +1,18 @@ + + + + false + true + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + From 0a09bc41a531a415174669e5f9f46320feeaab40 Mon Sep 17 00:00:00 2001 From: Fraser McLean Date: Thu, 29 May 2025 11:23:36 +0800 Subject: [PATCH 2/4] Add distributed application tests and update package references --- backend/Directory.Packages.props | 1 + .../tests/AppHost.Tests/AppHost.Tests.csproj | 6 ++++ .../DistributedApplicationFixture.cs | 33 +++++++++++++++++++ backend/tests/AppHost.Tests/GlobalUsings.cs | 2 ++ .../AppHost.Tests/HealthEndpointTests.cs | 19 +++++++++++ 5 files changed, 61 insertions(+) create mode 100644 backend/tests/AppHost.Tests/DistributedApplicationFixture.cs create mode 100644 backend/tests/AppHost.Tests/GlobalUsings.cs create mode 100644 backend/tests/AppHost.Tests/HealthEndpointTests.cs diff --git a/backend/Directory.Packages.props b/backend/Directory.Packages.props index 5f6fea1b..20e77741 100644 --- a/backend/Directory.Packages.props +++ b/backend/Directory.Packages.props @@ -10,6 +10,7 @@ + diff --git a/backend/tests/AppHost.Tests/AppHost.Tests.csproj b/backend/tests/AppHost.Tests/AppHost.Tests.csproj index ca15cc9c..b1c81cd0 100644 --- a/backend/tests/AppHost.Tests/AppHost.Tests.csproj +++ b/backend/tests/AppHost.Tests/AppHost.Tests.csproj @@ -6,13 +6,19 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + diff --git a/backend/tests/AppHost.Tests/DistributedApplicationFixture.cs b/backend/tests/AppHost.Tests/DistributedApplicationFixture.cs new file mode 100644 index 00000000..38a28136 --- /dev/null +++ b/backend/tests/AppHost.Tests/DistributedApplicationFixture.cs @@ -0,0 +1,33 @@ +using Aspire.Hosting; +using Aspire.Hosting.Testing; +using RateMyPet.AppHost.Tests; + +[assembly: AssemblyFixture(typeof(DistributedApplicationFixture))] + +namespace RateMyPet.AppHost.Tests; + +public sealed class DistributedApplicationFixture : IAsyncLifetime +{ + private DistributedApplication? app; + + public async ValueTask InitializeAsync() + { + var cancellationToken = TestContext.Current.CancellationToken; + + var appHost = await DistributedApplicationTestingBuilder + .CreateAsync(cancellationToken); + + app = await appHost.BuildAsync(cancellationToken); + + await app.StartAsync(cancellationToken).WaitAsync(TimeSpan.FromMinutes(1), cancellationToken); + } + + public HttpClient CreateHttpClient(string resourceName) + { + return app is not null + ? app.CreateHttpClient(resourceName) + : throw new InvalidOperationException("DistributedApplicationFixture has not been initialized."); + } + + public ValueTask DisposeAsync() => app?.DisposeAsync() ?? ValueTask.CompletedTask; +} diff --git a/backend/tests/AppHost.Tests/GlobalUsings.cs b/backend/tests/AppHost.Tests/GlobalUsings.cs new file mode 100644 index 00000000..f644bd9c --- /dev/null +++ b/backend/tests/AppHost.Tests/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using Shouldly; +global using Xunit; diff --git a/backend/tests/AppHost.Tests/HealthEndpointTests.cs b/backend/tests/AppHost.Tests/HealthEndpointTests.cs new file mode 100644 index 00000000..29d3d22a --- /dev/null +++ b/backend/tests/AppHost.Tests/HealthEndpointTests.cs @@ -0,0 +1,19 @@ +using System.Net; + +namespace RateMyPet.AppHost.Tests; + +public class HealthEndpointTests(DistributedApplicationFixture fixture) +{ + [Fact] + public async Task GetHealth_Should_ReturnOk() + { + // arrange + var httpClient = fixture.CreateHttpClient("api"); + + // act + var response = await httpClient.GetAsync("/health", TestContext.Current.CancellationToken); + + // assert + response.StatusCode.ShouldBe(HttpStatusCode.OK); + } +} From bef752e772582de7ddafea1cbb89f8da8d16d67e Mon Sep 17 00:00:00 2001 From: Fraser McLean Date: Thu, 29 May 2025 11:29:25 +0800 Subject: [PATCH 3/4] Increase app start timeout to 5 minutes --- backend/tests/AppHost.Tests/DistributedApplicationFixture.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/AppHost.Tests/DistributedApplicationFixture.cs b/backend/tests/AppHost.Tests/DistributedApplicationFixture.cs index 38a28136..3d9e853b 100644 --- a/backend/tests/AppHost.Tests/DistributedApplicationFixture.cs +++ b/backend/tests/AppHost.Tests/DistributedApplicationFixture.cs @@ -19,7 +19,7 @@ public async ValueTask InitializeAsync() app = await appHost.BuildAsync(cancellationToken); - await app.StartAsync(cancellationToken).WaitAsync(TimeSpan.FromMinutes(1), cancellationToken); + await app.StartAsync(cancellationToken).WaitAsync(TimeSpan.FromMinutes(5), cancellationToken); } public HttpClient CreateHttpClient(string resourceName) From 5caf2d422218d8499accb51887b2da965fa30134 Mon Sep 17 00:00:00 2001 From: Fraser McLean Date: Thu, 29 May 2025 14:20:15 +0800 Subject: [PATCH 4/4] Refactor app host fixture to extend DistributedApplicationFactory --- backend/tests/AppHost.Tests/AppHostFixture.cs | 16 +++++++++ .../DistributedApplicationFixture.cs | 33 ------------------- .../AppHost.Tests/HealthEndpointTests.cs | 2 +- 3 files changed, 17 insertions(+), 34 deletions(-) create mode 100644 backend/tests/AppHost.Tests/AppHostFixture.cs delete mode 100644 backend/tests/AppHost.Tests/DistributedApplicationFixture.cs diff --git a/backend/tests/AppHost.Tests/AppHostFixture.cs b/backend/tests/AppHost.Tests/AppHostFixture.cs new file mode 100644 index 00000000..86dc9ca4 --- /dev/null +++ b/backend/tests/AppHost.Tests/AppHostFixture.cs @@ -0,0 +1,16 @@ +using Aspire.Hosting; +using Aspire.Hosting.Testing; +using Microsoft.Extensions.Hosting; +using RateMyPet.AppHost.Tests; + +[assembly: AssemblyFixture(typeof(AppHostFixture))] + +namespace RateMyPet.AppHost.Tests; + +public sealed class AppHostFixture() : DistributedApplicationFactory(typeof(Projects.AppHost)), IAsyncLifetime +{ + public async ValueTask InitializeAsync() + { + await StartAsync(); + } +} diff --git a/backend/tests/AppHost.Tests/DistributedApplicationFixture.cs b/backend/tests/AppHost.Tests/DistributedApplicationFixture.cs deleted file mode 100644 index 3d9e853b..00000000 --- a/backend/tests/AppHost.Tests/DistributedApplicationFixture.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Aspire.Hosting; -using Aspire.Hosting.Testing; -using RateMyPet.AppHost.Tests; - -[assembly: AssemblyFixture(typeof(DistributedApplicationFixture))] - -namespace RateMyPet.AppHost.Tests; - -public sealed class DistributedApplicationFixture : IAsyncLifetime -{ - private DistributedApplication? app; - - public async ValueTask InitializeAsync() - { - var cancellationToken = TestContext.Current.CancellationToken; - - var appHost = await DistributedApplicationTestingBuilder - .CreateAsync(cancellationToken); - - app = await appHost.BuildAsync(cancellationToken); - - await app.StartAsync(cancellationToken).WaitAsync(TimeSpan.FromMinutes(5), cancellationToken); - } - - public HttpClient CreateHttpClient(string resourceName) - { - return app is not null - ? app.CreateHttpClient(resourceName) - : throw new InvalidOperationException("DistributedApplicationFixture has not been initialized."); - } - - public ValueTask DisposeAsync() => app?.DisposeAsync() ?? ValueTask.CompletedTask; -} diff --git a/backend/tests/AppHost.Tests/HealthEndpointTests.cs b/backend/tests/AppHost.Tests/HealthEndpointTests.cs index 29d3d22a..71b3c5e4 100644 --- a/backend/tests/AppHost.Tests/HealthEndpointTests.cs +++ b/backend/tests/AppHost.Tests/HealthEndpointTests.cs @@ -2,7 +2,7 @@ namespace RateMyPet.AppHost.Tests; -public class HealthEndpointTests(DistributedApplicationFixture fixture) +public class HealthEndpointTests(AppHostFixture fixture) { [Fact] public async Task GetHealth_Should_ReturnOk()