From efed37bf2167fd2a69b0a52ff73498d1498d0c3d Mon Sep 17 00:00:00 2001 From: Cam Soper Date: Mon, 9 Sep 2024 10:53:12 -0500 Subject: [PATCH 1/2] Corrections and clarifications (#1608) --- docs/database/ef-core-migrations.md | 4 ++++ docs/database/sql-server-integrations.md | 14 +++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/database/ef-core-migrations.md b/docs/database/ef-core-migrations.md index ce0ab8e6a..3e13e703e 100644 --- a/docs/database/ef-core-migrations.md +++ b/docs/database/ef-core-migrations.md @@ -155,3 +155,7 @@ Now that the migration service is configured, run the app to test the migrations ## Get the code You can find the [completed sample app on GitHub](https://github.com/MicrosoftDocs/aspire-docs-samples/tree/solution/SupportTicketApi). + +## More sample code + +The [Aspire Shop](/samples/dotnet/aspire-samples/aspire-shop/) sample app uses this approach to apply migrations. See the `AspireShop.CatalogDbManager` project for the migration service implementation. diff --git a/docs/database/sql-server-integrations.md b/docs/database/sql-server-integrations.md index fd8bf1440..29d060627 100644 --- a/docs/database/sql-server-integrations.md +++ b/docs/database/sql-server-integrations.md @@ -65,15 +65,23 @@ In the _:::no-loc text="Program.cs":::_ file of the _AspireSQLEFCore_ project, a This method accomplishes the following tasks: -- Registers a `TicketDbContext` with the DI container for connecting to the containerized Azure SQL Database. +- Registers a `TicketContext` with the DI container for connecting to the containerized Azure SQL Database. - Automatically enable corresponding health checks, logging, and telemetry. -## Migrate and seed the database +## Create the database -While developing locally, you need to create a database inside the SQL Server container. Update the _:::no-loc text="Program.cs":::_ file with the following code to automatically run Entity Framework migrations during startup. +While developing locally, you need to create a database inside the SQL Server container. Update the _:::no-loc text="Program.cs":::_ file with the following code: :::code language="csharp" source="snippets/tutorial/AspireSQLEFCore/AspireSQLEFCore/Program.cs" range="1-30" highlight="16-30"::: +The preceding code: + +- Checks if the app is running in a development environment. +- If it is, it retrieves the `TicketContext` service from the DI container and calls `Database.EnsureCreated()` to create the database if it doesn't already exist. + +> [!NOTE] +> Note that `EnsureCreated()` is not suitable for production environments, and it only creates the database as defined in the context. It doesn't apply any migrations. For more information on Entity Framework Core migrations in .NET Aspire, see [Apply Entity Framework Core migrations in .NET Aspire](ef-core-migrations.md). + ## Create the form The app requires a form for the user to be able to submit support ticket information and save the entry to the database. From 7c7010b926c2d2f27f12f0e04e1370773162f53c Mon Sep 17 00:00:00 2001 From: David Pine Date: Tue, 10 Sep 2024 06:57:37 -0500 Subject: [PATCH 2/2] Initial updates (#1607) * Initial updates * Spacing * Added a description of the env var test code * Adjust test name * A bit more words explaining tests * A bit of clarifications and rewording * More additions, tweaks, and updates. * Apply suggestions from code review Co-authored-by: Tom Dykstra --------- Co-authored-by: Tom Dykstra --- .../Properties/launchSettings.json | 4 +- .../AspireApp.AppHost.csproj | 3 +- .../mstest/AspireApp.AppHost/Program.cs | 3 -- .../Properties/launchSettings.json | 12 ++--- .../AspireApp.Tests/AspireApp.Tests.csproj | 2 +- .../mstest/AspireApp.Tests/EnvVarTests.cs | 26 +++++++++ .../mstest/AspireApp.Tests/WebTests.cs | 2 +- .../mstest/AspireApp.Web/AspireApp.Web.csproj | 4 -- .../testing/mstest/AspireApp.Web/Program.cs | 3 +- .../Properties/launchSettings.json | 4 +- .../mstest/AspireApp.Web/wwwroot/app.css | 4 +- .../snippets/testing/mstest/AspireApp.sln | 54 +++++++++---------- .../Properties/launchSettings.json | 4 +- .../AspireApp.AppHost.csproj | 3 +- .../nunit/AspireApp.AppHost/Program.cs | 3 -- .../Properties/launchSettings.json | 12 ++--- .../AspireApp.Tests/AspireApp.Tests.csproj | 8 +-- .../nunit/AspireApp.Tests/EnvVarTests.cs | 25 +++++++++ .../testing/nunit/AspireApp.Tests/WebTests.cs | 2 +- .../nunit/AspireApp.Web/AspireApp.Web.csproj | 4 -- .../testing/nunit/AspireApp.Web/Program.cs | 3 +- .../Properties/launchSettings.json | 4 +- .../nunit/AspireApp.Web/wwwroot/app.css | 4 +- .../snippets/testing/nunit/AspireApp.sln | 54 +++++++++---------- .../Properties/launchSettings.json | 4 +- .../AspireApp.AppHost.csproj | 3 +- .../xunit/AspireApp.AppHost/Program.cs | 3 -- .../Properties/launchSettings.json | 12 ++--- .../AspireApp.Tests/AspireApp.Tests.csproj | 2 +- .../xunit/AspireApp.Tests/EnvVarTests.cs | 28 ++++++++++ .../testing/xunit/AspireApp.Tests/WebTests.cs | 9 ++-- .../xunit/AspireApp.Web/AspireApp.Web.csproj | 4 -- .../testing/xunit/AspireApp.Web/Program.cs | 3 +- .../Properties/launchSettings.json | 4 +- .../xunit/AspireApp.Web/wwwroot/app.css | 4 +- .../snippets/testing/xunit/AspireApp.sln | 54 +++++++++---------- docs/fundamentals/testing.md | 44 ++++++++++++--- 37 files changed, 257 insertions(+), 164 deletions(-) create mode 100644 docs/fundamentals/snippets/testing/mstest/AspireApp.Tests/EnvVarTests.cs create mode 100644 docs/fundamentals/snippets/testing/nunit/AspireApp.Tests/EnvVarTests.cs create mode 100644 docs/fundamentals/snippets/testing/xunit/AspireApp.Tests/EnvVarTests.cs diff --git a/docs/fundamentals/snippets/testing/mstest/AspireApp.ApiService/Properties/launchSettings.json b/docs/fundamentals/snippets/testing/mstest/AspireApp.ApiService/Properties/launchSettings.json index c3bec024e..d9418f6d7 100644 --- a/docs/fundamentals/snippets/testing/mstest/AspireApp.ApiService/Properties/launchSettings.json +++ b/docs/fundamentals/snippets/testing/mstest/AspireApp.ApiService/Properties/launchSettings.json @@ -6,7 +6,7 @@ "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "weatherforecast", - "applicationUrl": "http://localhost:5324", + "applicationUrl": "http://localhost:5381", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } @@ -16,7 +16,7 @@ "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "weatherforecast", - "applicationUrl": "https://localhost:7518;http://localhost:5324", + "applicationUrl": "https://localhost:7369;http://localhost:5381", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/docs/fundamentals/snippets/testing/mstest/AspireApp.AppHost/AspireApp.AppHost.csproj b/docs/fundamentals/snippets/testing/mstest/AspireApp.AppHost/AspireApp.AppHost.csproj index d7ef762ec..9380625cf 100644 --- a/docs/fundamentals/snippets/testing/mstest/AspireApp.AppHost/AspireApp.AppHost.csproj +++ b/docs/fundamentals/snippets/testing/mstest/AspireApp.AppHost/AspireApp.AppHost.csproj @@ -6,7 +6,7 @@ enable enable true - c003beee-3095-46bd-a5fb-85f0280d1403 + 8832f6df-f7d3-4c65-8eab-22abf6e43ee8 @@ -16,7 +16,6 @@ - diff --git a/docs/fundamentals/snippets/testing/mstest/AspireApp.AppHost/Program.cs b/docs/fundamentals/snippets/testing/mstest/AspireApp.AppHost/Program.cs index 51959b006..39bbf7f81 100644 --- a/docs/fundamentals/snippets/testing/mstest/AspireApp.AppHost/Program.cs +++ b/docs/fundamentals/snippets/testing/mstest/AspireApp.AppHost/Program.cs @@ -1,12 +1,9 @@ var builder = DistributedApplication.CreateBuilder(args); -var cache = builder.AddRedis("cache"); - var apiService = builder.AddProject("apiservice"); builder.AddProject("webfrontend") .WithExternalHttpEndpoints() - .WithReference(cache) .WithReference(apiService); builder.Build().Run(); diff --git a/docs/fundamentals/snippets/testing/mstest/AspireApp.AppHost/Properties/launchSettings.json b/docs/fundamentals/snippets/testing/mstest/AspireApp.AppHost/Properties/launchSettings.json index 550d76abb..aa6371ce4 100644 --- a/docs/fundamentals/snippets/testing/mstest/AspireApp.AppHost/Properties/launchSettings.json +++ b/docs/fundamentals/snippets/testing/mstest/AspireApp.AppHost/Properties/launchSettings.json @@ -5,24 +5,24 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "https://localhost:17256;http://localhost:15121", + "applicationUrl": "https://localhost:17244;http://localhost:15088", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21034", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22227" + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21193", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22213" } }, "http": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "http://localhost:15121", + "applicationUrl": "http://localhost:15088", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19034", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20015" + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19275", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20199" } } } diff --git a/docs/fundamentals/snippets/testing/mstest/AspireApp.Tests/AspireApp.Tests.csproj b/docs/fundamentals/snippets/testing/mstest/AspireApp.Tests/AspireApp.Tests.csproj index b2807521b..220540bc3 100644 --- a/docs/fundamentals/snippets/testing/mstest/AspireApp.Tests/AspireApp.Tests.csproj +++ b/docs/fundamentals/snippets/testing/mstest/AspireApp.Tests/AspireApp.Tests.csproj @@ -15,7 +15,7 @@ - + diff --git a/docs/fundamentals/snippets/testing/mstest/AspireApp.Tests/EnvVarTests.cs b/docs/fundamentals/snippets/testing/mstest/AspireApp.Tests/EnvVarTests.cs new file mode 100644 index 000000000..eeaaae773 --- /dev/null +++ b/docs/fundamentals/snippets/testing/mstest/AspireApp.Tests/EnvVarTests.cs @@ -0,0 +1,26 @@ +namespace AspireApp.Tests; + +[TestClass] +public class EnvVarTests +{ + [TestMethod] + public async Task WebResourceEnvVarsResolveToApiService() + { + // Arrange + var appHost = await DistributedApplicationTestingBuilder + .CreateAsync(); + + var frontend = (IResourceWithEnvironment)appHost.Resources + .Single(static r => r.Name == "webfrontend"); + + // Act + var envVars = await frontend.GetEnvironmentVariableValuesAsync( + DistributedApplicationOperation.Publish); + + // Assert + CollectionAssert.Contains(envVars, + new KeyValuePair( + key: "services__apiservice__https__0", + value: "{apiservice.bindings.https.url}")); + } +} diff --git a/docs/fundamentals/snippets/testing/mstest/AspireApp.Tests/WebTests.cs b/docs/fundamentals/snippets/testing/mstest/AspireApp.Tests/WebTests.cs index b1e2b5bcd..dafa472b3 100644 --- a/docs/fundamentals/snippets/testing/mstest/AspireApp.Tests/WebTests.cs +++ b/docs/fundamentals/snippets/testing/mstest/AspireApp.Tests/WebTests.cs @@ -19,7 +19,7 @@ public async Task GetWebResourceRootReturnsOkStatusCode() var resourceNotificationService = app.Services .GetRequiredService(); - + await app.StartAsync(); // Act diff --git a/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/AspireApp.Web.csproj b/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/AspireApp.Web.csproj index 2e1f7c2c5..c9ba55ad5 100644 --- a/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/AspireApp.Web.csproj +++ b/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/AspireApp.Web.csproj @@ -10,8 +10,4 @@ - - - - diff --git a/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/Program.cs b/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/Program.cs index 08070b9d9..3c076c050 100644 --- a/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/Program.cs +++ b/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/Program.cs @@ -5,12 +5,13 @@ // Add service defaults & Aspire components. builder.AddServiceDefaults(); -builder.AddRedisOutputCache("cache"); // Add services to the container. builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); +builder.Services.AddOutputCache(); + builder.Services.AddHttpClient(client => { // This URL uses "https+http://" to indicate HTTPS is preferred over HTTP. diff --git a/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/Properties/launchSettings.json b/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/Properties/launchSettings.json index 12951b9d3..37b4a8b24 100644 --- a/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/Properties/launchSettings.json +++ b/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/Properties/launchSettings.json @@ -5,7 +5,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "http://localhost:5188", + "applicationUrl": "http://localhost:5154", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } @@ -14,7 +14,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "https://localhost:7034;http://localhost:5188", + "applicationUrl": "https://localhost:7226;http://localhost:5154", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/wwwroot/app.css b/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/wwwroot/app.css index 4670f1ba9..13ac0f936 100644 --- a/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/wwwroot/app.css +++ b/docs/fundamentals/snippets/testing/mstest/AspireApp.Web/wwwroot/app.css @@ -29,11 +29,11 @@ h1:focus { } .invalid { - outline: 1px solid #e51880; + outline: 1px solid #e51540; } .validation-message { - color: #e51880; + color: #e51540; } .blazor-error-boundary { diff --git a/docs/fundamentals/snippets/testing/mstest/AspireApp.sln b/docs/fundamentals/snippets/testing/mstest/AspireApp.sln index 10515ed1a..f8123b20c 100644 --- a/docs/fundamentals/snippets/testing/mstest/AspireApp.sln +++ b/docs/fundamentals/snippets/testing/mstest/AspireApp.sln @@ -1,16 +1,16 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 -VisualStudioVersion = 17.12.35125.258 +VisualStudioVersion = 17.12.35209.166 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.AppHost", "AspireApp.AppHost\AspireApp.AppHost.csproj", "{12497C1B-3914-4F0A-B66E-169E6CD32F7C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.AppHost", "AspireApp.AppHost\AspireApp.AppHost.csproj", "{EC46758A-CEC8-4167-A411-BA7C8FAA0568}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.ServiceDefaults", "AspireApp.ServiceDefaults\AspireApp.ServiceDefaults.csproj", "{DF30B3ED-82B3-4E9F-9704-371B86362514}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.ServiceDefaults", "AspireApp.ServiceDefaults\AspireApp.ServiceDefaults.csproj", "{C03045B9-8C3D-4E14-837F-E74D7E02D00A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.ApiService", "AspireApp.ApiService\AspireApp.ApiService.csproj", "{7DDDF326-E0AC-4AEE-85B2-69FA564E9465}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.ApiService", "AspireApp.ApiService\AspireApp.ApiService.csproj", "{4F099168-2B47-4298-AB97-0ECF25E3C380}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.Web", "AspireApp.Web\AspireApp.Web.csproj", "{AD54E041-CB6B-4E4E-948A-1B054E7FE236}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.Web", "AspireApp.Web\AspireApp.Web.csproj", "{5D051D94-C160-4A30-A66C-598729909737}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.Tests", "AspireApp.Tests\AspireApp.Tests.csproj", "{FE61106C-EB7D-455D-AE61-AB9636668A47}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.Tests", "AspireApp.Tests\AspireApp.Tests.csproj", "{F46802CC-1977-415B-830F-8D9088DA822A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -18,31 +18,31 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {12497C1B-3914-4F0A-B66E-169E6CD32F7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {12497C1B-3914-4F0A-B66E-169E6CD32F7C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {12497C1B-3914-4F0A-B66E-169E6CD32F7C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {12497C1B-3914-4F0A-B66E-169E6CD32F7C}.Release|Any CPU.Build.0 = Release|Any CPU - {DF30B3ED-82B3-4E9F-9704-371B86362514}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DF30B3ED-82B3-4E9F-9704-371B86362514}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DF30B3ED-82B3-4E9F-9704-371B86362514}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DF30B3ED-82B3-4E9F-9704-371B86362514}.Release|Any CPU.Build.0 = Release|Any CPU - {7DDDF326-E0AC-4AEE-85B2-69FA564E9465}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7DDDF326-E0AC-4AEE-85B2-69FA564E9465}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7DDDF326-E0AC-4AEE-85B2-69FA564E9465}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7DDDF326-E0AC-4AEE-85B2-69FA564E9465}.Release|Any CPU.Build.0 = Release|Any CPU - {AD54E041-CB6B-4E4E-948A-1B054E7FE236}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AD54E041-CB6B-4E4E-948A-1B054E7FE236}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AD54E041-CB6B-4E4E-948A-1B054E7FE236}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AD54E041-CB6B-4E4E-948A-1B054E7FE236}.Release|Any CPU.Build.0 = Release|Any CPU - {FE61106C-EB7D-455D-AE61-AB9636668A47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FE61106C-EB7D-455D-AE61-AB9636668A47}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FE61106C-EB7D-455D-AE61-AB9636668A47}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FE61106C-EB7D-455D-AE61-AB9636668A47}.Release|Any CPU.Build.0 = Release|Any CPU + {EC46758A-CEC8-4167-A411-BA7C8FAA0568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EC46758A-CEC8-4167-A411-BA7C8FAA0568}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EC46758A-CEC8-4167-A411-BA7C8FAA0568}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EC46758A-CEC8-4167-A411-BA7C8FAA0568}.Release|Any CPU.Build.0 = Release|Any CPU + {C03045B9-8C3D-4E14-837F-E74D7E02D00A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C03045B9-8C3D-4E14-837F-E74D7E02D00A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C03045B9-8C3D-4E14-837F-E74D7E02D00A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C03045B9-8C3D-4E14-837F-E74D7E02D00A}.Release|Any CPU.Build.0 = Release|Any CPU + {4F099168-2B47-4298-AB97-0ECF25E3C380}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F099168-2B47-4298-AB97-0ECF25E3C380}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F099168-2B47-4298-AB97-0ECF25E3C380}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F099168-2B47-4298-AB97-0ECF25E3C380}.Release|Any CPU.Build.0 = Release|Any CPU + {5D051D94-C160-4A30-A66C-598729909737}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5D051D94-C160-4A30-A66C-598729909737}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5D051D94-C160-4A30-A66C-598729909737}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5D051D94-C160-4A30-A66C-598729909737}.Release|Any CPU.Build.0 = Release|Any CPU + {F46802CC-1977-415B-830F-8D9088DA822A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F46802CC-1977-415B-830F-8D9088DA822A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F46802CC-1977-415B-830F-8D9088DA822A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F46802CC-1977-415B-830F-8D9088DA822A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {A88DD160-8742-4E48-ABE5-44D456516039} + SolutionGuid = {F2599B42-2481-4C8F-AC79-3029FC2FC444} EndGlobalSection EndGlobal diff --git a/docs/fundamentals/snippets/testing/nunit/AspireApp.ApiService/Properties/launchSettings.json b/docs/fundamentals/snippets/testing/nunit/AspireApp.ApiService/Properties/launchSettings.json index 82a717a89..3ed1a2b39 100644 --- a/docs/fundamentals/snippets/testing/nunit/AspireApp.ApiService/Properties/launchSettings.json +++ b/docs/fundamentals/snippets/testing/nunit/AspireApp.ApiService/Properties/launchSettings.json @@ -6,7 +6,7 @@ "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "weatherforecast", - "applicationUrl": "http://localhost:5317", + "applicationUrl": "http://localhost:5314", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } @@ -16,7 +16,7 @@ "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "weatherforecast", - "applicationUrl": "https://localhost:7578;http://localhost:5317", + "applicationUrl": "https://localhost:7560;http://localhost:5314", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/docs/fundamentals/snippets/testing/nunit/AspireApp.AppHost/AspireApp.AppHost.csproj b/docs/fundamentals/snippets/testing/nunit/AspireApp.AppHost/AspireApp.AppHost.csproj index b7f4c12fd..417c97181 100644 --- a/docs/fundamentals/snippets/testing/nunit/AspireApp.AppHost/AspireApp.AppHost.csproj +++ b/docs/fundamentals/snippets/testing/nunit/AspireApp.AppHost/AspireApp.AppHost.csproj @@ -6,7 +6,7 @@ enable enable true - b85dd0bb-63ef-4db6-b7a4-06df00663b65 + 2eb28899-ee86-44a2-b637-287cfc49eeaf @@ -16,7 +16,6 @@ - diff --git a/docs/fundamentals/snippets/testing/nunit/AspireApp.AppHost/Program.cs b/docs/fundamentals/snippets/testing/nunit/AspireApp.AppHost/Program.cs index 51959b006..39bbf7f81 100644 --- a/docs/fundamentals/snippets/testing/nunit/AspireApp.AppHost/Program.cs +++ b/docs/fundamentals/snippets/testing/nunit/AspireApp.AppHost/Program.cs @@ -1,12 +1,9 @@ var builder = DistributedApplication.CreateBuilder(args); -var cache = builder.AddRedis("cache"); - var apiService = builder.AddProject("apiservice"); builder.AddProject("webfrontend") .WithExternalHttpEndpoints() - .WithReference(cache) .WithReference(apiService); builder.Build().Run(); diff --git a/docs/fundamentals/snippets/testing/nunit/AspireApp.AppHost/Properties/launchSettings.json b/docs/fundamentals/snippets/testing/nunit/AspireApp.AppHost/Properties/launchSettings.json index fd6390f4d..63aedd049 100644 --- a/docs/fundamentals/snippets/testing/nunit/AspireApp.AppHost/Properties/launchSettings.json +++ b/docs/fundamentals/snippets/testing/nunit/AspireApp.AppHost/Properties/launchSettings.json @@ -5,24 +5,24 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "https://localhost:17035;http://localhost:15120", + "applicationUrl": "https://localhost:17064;http://localhost:15294", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21139", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22100" + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21173", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22005" } }, "http": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "http://localhost:15120", + "applicationUrl": "http://localhost:15294", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19016", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20120" + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19025", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20131" } } } diff --git a/docs/fundamentals/snippets/testing/nunit/AspireApp.Tests/AspireApp.Tests.csproj b/docs/fundamentals/snippets/testing/nunit/AspireApp.Tests/AspireApp.Tests.csproj index 2d3aaf9b5..87c217abb 100644 --- a/docs/fundamentals/snippets/testing/nunit/AspireApp.Tests/AspireApp.Tests.csproj +++ b/docs/fundamentals/snippets/testing/nunit/AspireApp.Tests/AspireApp.Tests.csproj @@ -11,10 +11,10 @@ - - - - + + + + diff --git a/docs/fundamentals/snippets/testing/nunit/AspireApp.Tests/EnvVarTests.cs b/docs/fundamentals/snippets/testing/nunit/AspireApp.Tests/EnvVarTests.cs new file mode 100644 index 000000000..456547886 --- /dev/null +++ b/docs/fundamentals/snippets/testing/nunit/AspireApp.Tests/EnvVarTests.cs @@ -0,0 +1,25 @@ +namespace AspireApp.Tests; + +public class EnvVarTests +{ + [Test] + public async Task WebResourceEnvVarsResolveToApiService() + { + // Arrange + var appHost = await DistributedApplicationTestingBuilder + .CreateAsync(); + + var frontend = (IResourceWithEnvironment)appHost.Resources + .Single(static r => r.Name == "webfrontend"); + + // Act + var envVars = await frontend.GetEnvironmentVariableValuesAsync( + DistributedApplicationOperation.Publish); + + // Assert + Assert.That(envVars, Does.Contain( + new KeyValuePair( + key: "services__apiservice__https__0", + value: "{apiservice.bindings.https.url}"))); + } +} diff --git a/docs/fundamentals/snippets/testing/nunit/AspireApp.Tests/WebTests.cs b/docs/fundamentals/snippets/testing/nunit/AspireApp.Tests/WebTests.cs index a0791b13a..38008b0f0 100644 --- a/docs/fundamentals/snippets/testing/nunit/AspireApp.Tests/WebTests.cs +++ b/docs/fundamentals/snippets/testing/nunit/AspireApp.Tests/WebTests.cs @@ -18,7 +18,7 @@ public async Task GetWebResourceRootReturnsOkStatusCode() var resourceNotificationService = app.Services .GetRequiredService(); - + await app.StartAsync(); // Act diff --git a/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/AspireApp.Web.csproj b/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/AspireApp.Web.csproj index 2e1f7c2c5..c9ba55ad5 100644 --- a/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/AspireApp.Web.csproj +++ b/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/AspireApp.Web.csproj @@ -10,8 +10,4 @@ - - - - diff --git a/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/Program.cs b/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/Program.cs index 08070b9d9..3c076c050 100644 --- a/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/Program.cs +++ b/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/Program.cs @@ -5,12 +5,13 @@ // Add service defaults & Aspire components. builder.AddServiceDefaults(); -builder.AddRedisOutputCache("cache"); // Add services to the container. builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); +builder.Services.AddOutputCache(); + builder.Services.AddHttpClient(client => { // This URL uses "https+http://" to indicate HTTPS is preferred over HTTP. diff --git a/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/Properties/launchSettings.json b/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/Properties/launchSettings.json index 1457cf210..2d8a6797b 100644 --- a/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/Properties/launchSettings.json +++ b/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/Properties/launchSettings.json @@ -5,7 +5,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "http://localhost:5037", + "applicationUrl": "http://localhost:5265", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } @@ -14,7 +14,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "https://localhost:7006;http://localhost:5037", + "applicationUrl": "https://localhost:7043;http://localhost:5265", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/wwwroot/app.css b/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/wwwroot/app.css index 00fcd1899..430a4ba2e 100644 --- a/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/wwwroot/app.css +++ b/docs/fundamentals/snippets/testing/nunit/AspireApp.Web/wwwroot/app.css @@ -29,11 +29,11 @@ h1:focus { } .invalid { - outline: 1px solid #e50370; + outline: 1px solid #e52650; } .validation-message { - color: #e50370; + color: #e52650; } .blazor-error-boundary { diff --git a/docs/fundamentals/snippets/testing/nunit/AspireApp.sln b/docs/fundamentals/snippets/testing/nunit/AspireApp.sln index 412160656..76ce27301 100644 --- a/docs/fundamentals/snippets/testing/nunit/AspireApp.sln +++ b/docs/fundamentals/snippets/testing/nunit/AspireApp.sln @@ -1,16 +1,16 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 -VisualStudioVersion = 17.12.35125.258 +VisualStudioVersion = 17.12.35209.166 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.AppHost", "AspireApp.AppHost\AspireApp.AppHost.csproj", "{A4DD849A-AE56-4838-9865-A9BE8A08B562}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.AppHost", "AspireApp.AppHost\AspireApp.AppHost.csproj", "{563C31E6-B0EC-477A-B1EA-3AC2CAA54DCC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.ServiceDefaults", "AspireApp.ServiceDefaults\AspireApp.ServiceDefaults.csproj", "{2344FF00-97E5-4A7E-B8D6-6CB0F44C51BB}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.ServiceDefaults", "AspireApp.ServiceDefaults\AspireApp.ServiceDefaults.csproj", "{92112C37-460E-4F33-8F35-85A3A2A92061}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.ApiService", "AspireApp.ApiService\AspireApp.ApiService.csproj", "{1FE37A4B-27A2-4757-87F7-21B19A3E287B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.ApiService", "AspireApp.ApiService\AspireApp.ApiService.csproj", "{8DC401BC-A4FD-4D6C-B2A7-958E010773F5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.Web", "AspireApp.Web\AspireApp.Web.csproj", "{39882682-2E76-4E30-ADF6-BE89F2EC6DEC}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.Web", "AspireApp.Web\AspireApp.Web.csproj", "{F0F8B1A3-2B88-44F3-B2B2-10CA44E150E0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.Tests", "AspireApp.Tests\AspireApp.Tests.csproj", "{2D417620-D6EF-4FE3-8A4D-87527B6AEB63}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.Tests", "AspireApp.Tests\AspireApp.Tests.csproj", "{AD840ABF-B96E-49C9-A8BE-4A7C5357F3FB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -18,31 +18,31 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A4DD849A-AE56-4838-9865-A9BE8A08B562}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A4DD849A-AE56-4838-9865-A9BE8A08B562}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A4DD849A-AE56-4838-9865-A9BE8A08B562}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A4DD849A-AE56-4838-9865-A9BE8A08B562}.Release|Any CPU.Build.0 = Release|Any CPU - {2344FF00-97E5-4A7E-B8D6-6CB0F44C51BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2344FF00-97E5-4A7E-B8D6-6CB0F44C51BB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2344FF00-97E5-4A7E-B8D6-6CB0F44C51BB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2344FF00-97E5-4A7E-B8D6-6CB0F44C51BB}.Release|Any CPU.Build.0 = Release|Any CPU - {1FE37A4B-27A2-4757-87F7-21B19A3E287B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1FE37A4B-27A2-4757-87F7-21B19A3E287B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1FE37A4B-27A2-4757-87F7-21B19A3E287B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1FE37A4B-27A2-4757-87F7-21B19A3E287B}.Release|Any CPU.Build.0 = Release|Any CPU - {39882682-2E76-4E30-ADF6-BE89F2EC6DEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {39882682-2E76-4E30-ADF6-BE89F2EC6DEC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {39882682-2E76-4E30-ADF6-BE89F2EC6DEC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {39882682-2E76-4E30-ADF6-BE89F2EC6DEC}.Release|Any CPU.Build.0 = Release|Any CPU - {2D417620-D6EF-4FE3-8A4D-87527B6AEB63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2D417620-D6EF-4FE3-8A4D-87527B6AEB63}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2D417620-D6EF-4FE3-8A4D-87527B6AEB63}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2D417620-D6EF-4FE3-8A4D-87527B6AEB63}.Release|Any CPU.Build.0 = Release|Any CPU + {563C31E6-B0EC-477A-B1EA-3AC2CAA54DCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {563C31E6-B0EC-477A-B1EA-3AC2CAA54DCC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {563C31E6-B0EC-477A-B1EA-3AC2CAA54DCC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {563C31E6-B0EC-477A-B1EA-3AC2CAA54DCC}.Release|Any CPU.Build.0 = Release|Any CPU + {92112C37-460E-4F33-8F35-85A3A2A92061}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {92112C37-460E-4F33-8F35-85A3A2A92061}.Debug|Any CPU.Build.0 = Debug|Any CPU + {92112C37-460E-4F33-8F35-85A3A2A92061}.Release|Any CPU.ActiveCfg = Release|Any CPU + {92112C37-460E-4F33-8F35-85A3A2A92061}.Release|Any CPU.Build.0 = Release|Any CPU + {8DC401BC-A4FD-4D6C-B2A7-958E010773F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8DC401BC-A4FD-4D6C-B2A7-958E010773F5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8DC401BC-A4FD-4D6C-B2A7-958E010773F5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8DC401BC-A4FD-4D6C-B2A7-958E010773F5}.Release|Any CPU.Build.0 = Release|Any CPU + {F0F8B1A3-2B88-44F3-B2B2-10CA44E150E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F0F8B1A3-2B88-44F3-B2B2-10CA44E150E0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F0F8B1A3-2B88-44F3-B2B2-10CA44E150E0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F0F8B1A3-2B88-44F3-B2B2-10CA44E150E0}.Release|Any CPU.Build.0 = Release|Any CPU + {AD840ABF-B96E-49C9-A8BE-4A7C5357F3FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD840ABF-B96E-49C9-A8BE-4A7C5357F3FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD840ABF-B96E-49C9-A8BE-4A7C5357F3FB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD840ABF-B96E-49C9-A8BE-4A7C5357F3FB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {09E8E3E1-AAEA-4C0A-9B36-5CE505AEA178} + SolutionGuid = {87D6D96F-C34C-434F-9346-842476F8B485} EndGlobalSection EndGlobal diff --git a/docs/fundamentals/snippets/testing/xunit/AspireApp.ApiService/Properties/launchSettings.json b/docs/fundamentals/snippets/testing/xunit/AspireApp.ApiService/Properties/launchSettings.json index 9417c5647..c60be9dbd 100644 --- a/docs/fundamentals/snippets/testing/xunit/AspireApp.ApiService/Properties/launchSettings.json +++ b/docs/fundamentals/snippets/testing/xunit/AspireApp.ApiService/Properties/launchSettings.json @@ -6,7 +6,7 @@ "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "weatherforecast", - "applicationUrl": "http://localhost:5447", + "applicationUrl": "http://localhost:5344", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } @@ -16,7 +16,7 @@ "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "weatherforecast", - "applicationUrl": "https://localhost:7568;http://localhost:5447", + "applicationUrl": "https://localhost:7371;http://localhost:5344", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/docs/fundamentals/snippets/testing/xunit/AspireApp.AppHost/AspireApp.AppHost.csproj b/docs/fundamentals/snippets/testing/xunit/AspireApp.AppHost/AspireApp.AppHost.csproj index 37fc179c5..57dbcfe3a 100644 --- a/docs/fundamentals/snippets/testing/xunit/AspireApp.AppHost/AspireApp.AppHost.csproj +++ b/docs/fundamentals/snippets/testing/xunit/AspireApp.AppHost/AspireApp.AppHost.csproj @@ -6,7 +6,7 @@ enable enable true - aa54ca1a-f273-459a-abc1-ae283a6ad177 + c5ce4aa4-0324-4023-9e36-94433cef32dc @@ -16,7 +16,6 @@ - diff --git a/docs/fundamentals/snippets/testing/xunit/AspireApp.AppHost/Program.cs b/docs/fundamentals/snippets/testing/xunit/AspireApp.AppHost/Program.cs index 51959b006..39bbf7f81 100644 --- a/docs/fundamentals/snippets/testing/xunit/AspireApp.AppHost/Program.cs +++ b/docs/fundamentals/snippets/testing/xunit/AspireApp.AppHost/Program.cs @@ -1,12 +1,9 @@ var builder = DistributedApplication.CreateBuilder(args); -var cache = builder.AddRedis("cache"); - var apiService = builder.AddProject("apiservice"); builder.AddProject("webfrontend") .WithExternalHttpEndpoints() - .WithReference(cache) .WithReference(apiService); builder.Build().Run(); diff --git a/docs/fundamentals/snippets/testing/xunit/AspireApp.AppHost/Properties/launchSettings.json b/docs/fundamentals/snippets/testing/xunit/AspireApp.AppHost/Properties/launchSettings.json index fb6ce3590..ec6c91fd8 100644 --- a/docs/fundamentals/snippets/testing/xunit/AspireApp.AppHost/Properties/launchSettings.json +++ b/docs/fundamentals/snippets/testing/xunit/AspireApp.AppHost/Properties/launchSettings.json @@ -5,24 +5,24 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "https://localhost:17291;http://localhost:15031", + "applicationUrl": "https://localhost:17151;http://localhost:15106", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21049", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22076" + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21144", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22292" } }, "http": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "http://localhost:15031", + "applicationUrl": "http://localhost:15106", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19103", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20070" + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19007", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20066" } } } diff --git a/docs/fundamentals/snippets/testing/xunit/AspireApp.Tests/AspireApp.Tests.csproj b/docs/fundamentals/snippets/testing/xunit/AspireApp.Tests/AspireApp.Tests.csproj index 559882e7b..b13555d58 100644 --- a/docs/fundamentals/snippets/testing/xunit/AspireApp.Tests/AspireApp.Tests.csproj +++ b/docs/fundamentals/snippets/testing/xunit/AspireApp.Tests/AspireApp.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/docs/fundamentals/snippets/testing/xunit/AspireApp.Tests/EnvVarTests.cs b/docs/fundamentals/snippets/testing/xunit/AspireApp.Tests/EnvVarTests.cs new file mode 100644 index 000000000..b8f7f982b --- /dev/null +++ b/docs/fundamentals/snippets/testing/xunit/AspireApp.Tests/EnvVarTests.cs @@ -0,0 +1,28 @@ +namespace AspireApp.Tests; + +public class EnvVarTests +{ + [Fact] + public async Task WebResourceEnvVarsResolveToApiService() + { + // Arrange + var appHost = await DistributedApplicationTestingBuilder + .CreateAsync(); + + var frontend = (IResourceWithEnvironment)appHost.Resources + .Single(static r => r.Name == "webfrontend"); + + // Act + var envVars = await frontend.GetEnvironmentVariableValuesAsync( + DistributedApplicationOperation.Publish); + + // Assert + Assert.Contains(envVars, static (kvp) => + { + var (key, value) = kvp; + + return key is "services__apiservice__https__0" + && value is "{apiservice.bindings.https.url}"; + }); + } +} diff --git a/docs/fundamentals/snippets/testing/xunit/AspireApp.Tests/WebTests.cs b/docs/fundamentals/snippets/testing/xunit/AspireApp.Tests/WebTests.cs index 5a7fe5039..ec4130d72 100644 --- a/docs/fundamentals/snippets/testing/xunit/AspireApp.Tests/WebTests.cs +++ b/docs/fundamentals/snippets/testing/xunit/AspireApp.Tests/WebTests.cs @@ -1,4 +1,4 @@ -namespace AspireApp.Tests; +namespace AspireApp.Tests; public class WebTests { @@ -14,18 +14,21 @@ public async Task GetWebResourceRootReturnsOkStatusCode() clientBuilder.AddStandardResilienceHandler(); }); + // To output logs to the xUnit.net ITestOutputHelper, + // consider adding a package from https://www.nuget.org/packages?q=xunit+logging + await using var app = await appHost.BuildAsync(); var resourceNotificationService = app.Services .GetRequiredService(); - + await app.StartAsync(); // Act var httpClient = app.CreateHttpClient("webfrontend"); await resourceNotificationService.WaitForResourceAsync( - "webfrontend", + "webfrontend", KnownResourceStates.Running ) .WaitAsync(TimeSpan.FromSeconds(30)); diff --git a/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/AspireApp.Web.csproj b/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/AspireApp.Web.csproj index 2e1f7c2c5..c9ba55ad5 100644 --- a/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/AspireApp.Web.csproj +++ b/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/AspireApp.Web.csproj @@ -10,8 +10,4 @@ - - - - diff --git a/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/Program.cs b/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/Program.cs index 08070b9d9..3c076c050 100644 --- a/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/Program.cs +++ b/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/Program.cs @@ -5,12 +5,13 @@ // Add service defaults & Aspire components. builder.AddServiceDefaults(); -builder.AddRedisOutputCache("cache"); // Add services to the container. builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); +builder.Services.AddOutputCache(); + builder.Services.AddHttpClient(client => { // This URL uses "https+http://" to indicate HTTPS is preferred over HTTP. diff --git a/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/Properties/launchSettings.json b/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/Properties/launchSettings.json index fe89fec46..4c49181a3 100644 --- a/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/Properties/launchSettings.json +++ b/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/Properties/launchSettings.json @@ -5,7 +5,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "http://localhost:5226", + "applicationUrl": "http://localhost:5129", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } @@ -14,7 +14,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "https://localhost:7057;http://localhost:5226", + "applicationUrl": "https://localhost:7064;http://localhost:5129", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/wwwroot/app.css b/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/wwwroot/app.css index 58fb1fe99..32a813b21 100644 --- a/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/wwwroot/app.css +++ b/docs/fundamentals/snippets/testing/xunit/AspireApp.Web/wwwroot/app.css @@ -29,11 +29,11 @@ h1:focus { } .invalid { - outline: 1px solid #e52260; + outline: 1px solid #e51290; } .validation-message { - color: #e52260; + color: #e51290; } .blazor-error-boundary { diff --git a/docs/fundamentals/snippets/testing/xunit/AspireApp.sln b/docs/fundamentals/snippets/testing/xunit/AspireApp.sln index 51b54603b..4490060c8 100644 --- a/docs/fundamentals/snippets/testing/xunit/AspireApp.sln +++ b/docs/fundamentals/snippets/testing/xunit/AspireApp.sln @@ -1,16 +1,16 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 -VisualStudioVersion = 17.12.35125.258 +VisualStudioVersion = 17.12.35209.166 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.AppHost", "AspireApp.AppHost\AspireApp.AppHost.csproj", "{6C476083-B6BB-4203-8BF6-22AAC8127C66}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.AppHost", "AspireApp.AppHost\AspireApp.AppHost.csproj", "{FB5300E0-39B1-4193-8CE6-A1F174FA5B14}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.ServiceDefaults", "AspireApp.ServiceDefaults\AspireApp.ServiceDefaults.csproj", "{DC5F4E14-F3EE-4650-B255-AB45319D006C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.ServiceDefaults", "AspireApp.ServiceDefaults\AspireApp.ServiceDefaults.csproj", "{134A604A-CB49-42E9-AD54-BFA36EE524D8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.ApiService", "AspireApp.ApiService\AspireApp.ApiService.csproj", "{8CDDFE3A-86B3-44B5-8434-4252C4580353}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.ApiService", "AspireApp.ApiService\AspireApp.ApiService.csproj", "{1F5196E9-278D-4724-9F75-905AA9970F76}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.Web", "AspireApp.Web\AspireApp.Web.csproj", "{0FA30464-EC42-40C9-B542-EC2A42AFAF81}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.Web", "AspireApp.Web\AspireApp.Web.csproj", "{8517CD42-6F1C-43A0-8C7A-36C0D1DC7D9E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.Tests", "AspireApp.Tests\AspireApp.Tests.csproj", "{67F095A4-0235-49CB-AA3E-E8DE5A4877C5}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspireApp.Tests", "AspireApp.Tests\AspireApp.Tests.csproj", "{96C82AC7-9D07-48DF-A9F1-7055C2B13B31}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -18,31 +18,31 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6C476083-B6BB-4203-8BF6-22AAC8127C66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6C476083-B6BB-4203-8BF6-22AAC8127C66}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6C476083-B6BB-4203-8BF6-22AAC8127C66}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6C476083-B6BB-4203-8BF6-22AAC8127C66}.Release|Any CPU.Build.0 = Release|Any CPU - {DC5F4E14-F3EE-4650-B255-AB45319D006C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DC5F4E14-F3EE-4650-B255-AB45319D006C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DC5F4E14-F3EE-4650-B255-AB45319D006C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DC5F4E14-F3EE-4650-B255-AB45319D006C}.Release|Any CPU.Build.0 = Release|Any CPU - {8CDDFE3A-86B3-44B5-8434-4252C4580353}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8CDDFE3A-86B3-44B5-8434-4252C4580353}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8CDDFE3A-86B3-44B5-8434-4252C4580353}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8CDDFE3A-86B3-44B5-8434-4252C4580353}.Release|Any CPU.Build.0 = Release|Any CPU - {0FA30464-EC42-40C9-B542-EC2A42AFAF81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0FA30464-EC42-40C9-B542-EC2A42AFAF81}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0FA30464-EC42-40C9-B542-EC2A42AFAF81}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0FA30464-EC42-40C9-B542-EC2A42AFAF81}.Release|Any CPU.Build.0 = Release|Any CPU - {67F095A4-0235-49CB-AA3E-E8DE5A4877C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {67F095A4-0235-49CB-AA3E-E8DE5A4877C5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {67F095A4-0235-49CB-AA3E-E8DE5A4877C5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {67F095A4-0235-49CB-AA3E-E8DE5A4877C5}.Release|Any CPU.Build.0 = Release|Any CPU + {FB5300E0-39B1-4193-8CE6-A1F174FA5B14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB5300E0-39B1-4193-8CE6-A1F174FA5B14}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB5300E0-39B1-4193-8CE6-A1F174FA5B14}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB5300E0-39B1-4193-8CE6-A1F174FA5B14}.Release|Any CPU.Build.0 = Release|Any CPU + {134A604A-CB49-42E9-AD54-BFA36EE524D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {134A604A-CB49-42E9-AD54-BFA36EE524D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {134A604A-CB49-42E9-AD54-BFA36EE524D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {134A604A-CB49-42E9-AD54-BFA36EE524D8}.Release|Any CPU.Build.0 = Release|Any CPU + {1F5196E9-278D-4724-9F75-905AA9970F76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1F5196E9-278D-4724-9F75-905AA9970F76}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1F5196E9-278D-4724-9F75-905AA9970F76}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1F5196E9-278D-4724-9F75-905AA9970F76}.Release|Any CPU.Build.0 = Release|Any CPU + {8517CD42-6F1C-43A0-8C7A-36C0D1DC7D9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8517CD42-6F1C-43A0-8C7A-36C0D1DC7D9E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8517CD42-6F1C-43A0-8C7A-36C0D1DC7D9E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8517CD42-6F1C-43A0-8C7A-36C0D1DC7D9E}.Release|Any CPU.Build.0 = Release|Any CPU + {96C82AC7-9D07-48DF-A9F1-7055C2B13B31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96C82AC7-9D07-48DF-A9F1-7055C2B13B31}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96C82AC7-9D07-48DF-A9F1-7055C2B13B31}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96C82AC7-9D07-48DF-A9F1-7055C2B13B31}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {B767D03E-AF7C-4C84-B930-9CE271EE754E} + SolutionGuid = {EC02C850-F362-4965-BCEC-93A51099F72F} EndGlobalSection EndGlobal diff --git a/docs/fundamentals/testing.md b/docs/fundamentals/testing.md index 0e523d98d..adc3fb25d 100644 --- a/docs/fundamentals/testing.md +++ b/docs/fundamentals/testing.md @@ -1,13 +1,15 @@ --- -title: Testing .NET Aspire projects -description: Learn how to test your .NET Aspire projects using the xUnit testing framework. -ms.date: 07/26/2024 +title: Testing .NET Aspire solutions +description: Learn how to test your .NET Aspire solutions using the xUnit, NUnit, and MSTest testing frameworks. +ms.date: 09/09/2024 zone_pivot_groups: unit-testing-framework --- -# Testing .NET Aspire projects +# Testing .NET Aspire solutions -In this article, you'll learn how to create a test project, write, and run tests for your .NET Aspire projects. The tests in this article are not unit tests, but rather functional or integration tests. .NET Aspire include an [testing project templates](setup-tooling.md#net-aspire-project-templates) that you can use to test your .NET Aspire projects. The testing project templates are available for MSTest, NUnit, and xUnit testing frameworks and includes a sample test that you can use as a starting point for your tests. +In this article, you learn how to create a test project, write tests, and run them for your .NET Aspire solutions. The tests in this article aren't unit tests, but rather functional or integration tests. .NET Aspire includes several variations of [testing project templates](setup-tooling.md#net-aspire-project-templates) that you can use to test your .NET Aspire resource dependencies—and their communications. The testing project templates are available for MSTest, NUnit, and xUnit testing frameworks and include a sample test that you can use as a starting point for your tests. + +The .NET Aspire test project templates rely on the [Aspire.Hosting.Testing](https://www.nuget.org/packages/Aspire.Hosting.Testing) NuGet package. This package exposes the `DistributedApplicationTestingBuilder` class, which is used to create a test host for your distributed application. The distributed application testing builder relies on the `DistributedApplication` class to create and start the [app host](app-host-overview.md). ## Create a test project @@ -94,9 +96,39 @@ The preceding code: - A simple HTTP GET request is made to the root of the `webfrontend` resource. - The test asserts that the response status code is `OK`. +## Test resource environment variables + +To further test resources and their expressed dependencies in your .NET Aspire solution, you can assert that environment variables are injected correctly. The following example demonstrates how to test that the `webfrontend` resource has an HTTPS environment variable that resolves to the `apiservice` resource: + +:::zone pivot="xunit" + +:::code language="csharp" source="snippets/testing/xunit/AspireApp.Tests/EnvVarTests.cs"::: + +:::zone-end +:::zone pivot="mstest" + +:::code language="csharp" source="snippets/testing/mstest/AspireApp.Tests/EnvVarTests.cs"::: + +:::zone-end +:::zone pivot="nunit" + +:::code language="csharp" source="snippets/testing/nunit/AspireApp.Tests/EnvVarTests.cs"::: + +:::zone-end + +The preceding code: + +- Relies on the `DistributedApplicationTestingBuilder` to asynchronously create the app host. +- The `builder` instance is used to retrieve an `IResourceWithEnvironment` instance named "webfrontend" from the . +- The `webfrontend` resource is used to call to retrieve its configured environment variables. +- The `DistributedApplicationOperation.Publish` argument is passed when calling `GetEnvironmentVariableValuesAsync` to specify environment variables that are published to the resource as binding expressions. +- With the returned environment variables, the test asserts that the `webfrontend` resource has an HTTPS environment variable that resolves to the `apiservice` resource. + ## Summary -By using the .NET Aspire testing project template, you can easily create test projects for your .NET Aspire projects. The template project includes a sample test that you can use as a starting point for your tests. The `DistributedApplicationTestingBuilder` follows a familiar pattern to the `WebApplicationFactory` in ASP.NET Core. It allows you to create a test host for your distributed application and run tests against it. +The .NET Aspire testing project template makes it easier to create test projects for .NET Aspire solutions. The template project includes a sample test that you can use as a starting point for your tests. The `DistributedApplicationTestingBuilder` follows a familiar pattern to the `WebApplicationFactory` in ASP.NET Core. It allows you to create a test host for your distributed application and run tests against it. + +Finally, when using the `DistributedApplicationTestingBuilder` all resource logs are redirected to the `DistributedApplication` by default. The redirection of resource logs enables scenarios where you want to assert that a resource is logging correctly. ## See also