diff --git a/docs/database/ef-core-migrations.md b/docs/database/ef-core-migrations.md index ce0ab8e6ac..3e13e703e4 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 fd8bf14404..29d0606278 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. 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 c3bec024e9..d9418f6d71 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 d7ef762eca..9380625cf7 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 51959b006c..39bbf7f813 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 550d76abb9..aa6371ce42 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 b2807521b1..220540bc36 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 0000000000..eeaaae773e --- /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 b1e2b5bcdc..dafa472b31 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 2e1f7c2c58..c9ba55ad5f 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 08070b9d90..3c076c050f 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 12951b9d32..37b4a8b24c 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 4670f1ba9f..13ac0f9365 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 10515ed1a0..f8123b20c7 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 82a717a899..3ed1a2b39f 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 b7f4c12fdb..417c97181b 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 51959b006c..39bbf7f813 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 fd6390f4d5..63aedd049c 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 2d3aaf9b5d..87c217abb6 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 0000000000..4565478869 --- /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 a0791b13a2..38008b0f06 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 2e1f7c2c58..c9ba55ad5f 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 08070b9d90..3c076c050f 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 1457cf2107..2d8a6797b8 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 00fcd1899a..430a4ba2e7 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 412160656d..76ce27301a 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 9417c56474..c60be9dbdc 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 37fc179c58..57dbcfe3ad 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 51959b006c..39bbf7f813 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 fb6ce3590c..ec6c91fd8d 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 559882e7b6..b13555d58e 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 0000000000..b8f7f982bb --- /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 5a7fe5039b..ec4130d725 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 2e1f7c2c58..c9ba55ad5f 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 08070b9d90..3c076c050f 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 fe89fec466..4c49181a33 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 58fb1fe995..32a813b218 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 51b54603bf..4490060c8d 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 0e523d98d4..adc3fb25df 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