Lesson 3.8.1 had a paragraph on Aspire tests in outline, with this sentence in it: such tests are slow, because they start everything, and they check a lot at once; use them for a few paths from end to end. This lesson builds exactly one such path: a visitor books an appointment, the Kladde stores the booking, and the outbox sends the confirmation. In between lie the web app, SQL Server, the migrations, the outbox’s background service and the configuration the AppHost hands to all of them. No other test in the Kladde checks how all these parts work together with the wiring they use on your machine too.
The whole AppHost in a test
The package Aspire.Hosting.Testing starts an AppHost in a test. The test gets the same model that aspire run starts, with three differences:
the dashboard is off, the ports are chosen at random so that several runs can go side by side, and the test can change the model before it
starts.
IDistributedApplicationTestingBuilder builder =
await DistributedApplicationTestingBuilder.CreateAsync<Projects.Kladde_AppHost>(args, cancellationToken);
// ... change the model ...
DistributedApplication app = await builder.BuildAsync(cancellationToken);
await app.StartAsync(cancellationToken);
await app.ResourceNotifications.WaitForResourceHealthyAsync("web", cancellationToken);
CreateAsync<Projects.Kladde_AppHost>(args, …)runsAppHost.csup tobuilder.Build()and stops the model before anything starts.Projects.Kladde_AppHostexists as soon as the test project references the AppHost.argsgo into the AppHost’s configuration, as withaspire run -- ….BuildAsyncandStartAsyncbuild and start the model.StartAsyncreturns when everything has started, not when everything is ready.ResourceNotifications.WaitForResourceHealthyAsync("web", …)waits until the health check from lesson 3.14.1 succeeds. Becausewebstarts only after the migrations and/health/readychecks the database, the test thereby waits for everything a booking needs.app.CreateHttpClient("web", "https")gives you anHttpClientwhose base address is thehttpsendpoint ofweb, with this run’s random port.app.ResourceCommands.ExecuteCommandAsync("web", "test-data", …)runs a command the way the dashboard does, including the one from lesson 3.14.1. Its result is inSuccess,Messageand, withResultMode = HttpCommandResultMode.Text, inData.Value.
An Aspire test starts processes and containers, not classes in the test process. So you can’t replace a service inside the web app’s container the
way WebApplicationFactory allows. Whatever a test wants to change, it changes through the model: arguments, environment variables, resources.