Skip to content

Support .NET Aspire multi-host (inter-domain) testing alongside WebApplicationFactory #105

Description

@chullybun

Summary

Implemented in #106: UnitTestEx.Aspire, a second, opt-in testing tier for genuine multi-host, inter-domain interactions (e.g. Shopping calling Products, both calling an external payment/mail gateway) via Aspire.Hosting.Testing.DistributedApplicationTestingBuilder - alongside, not replacing, today's intra-domain, single-host testing via WebApplicationFactory/ApiTesterBase.

See the README's Aspire multi-host testing section for full usage once merged.

What's delivered

  • Two tiers, picked per test goal:
    • Tier 1 (unchanged): ApiTesterBase/WebApplicationFactory/MockHttpClientFactory - full in-process DI reach-in for deep, single-service isolation testing.
    • Tier 2 (new): UnitTestEx.Aspire (net8.0+) with AspireTester/AspireTesterBase<TAppHost, TSelf> wrapping DistributedApplicationTestingBuilder - real separate processes, real service discovery, for testing genuine interaction between two or more domains.
  • Compile-time tier boundary: a new TesterBaseCore holds only the genuinely host-agnostic members; Tier 1's TesterBase keeps its full DI-replacement surface on top of it, while Tier 2's AspireTesterBase inherits TesterBaseCore directly - DI-replacement methods simply don't exist on a Tier 2 tester, rather than throwing at runtime. A new IHttpClientSource interface lets the existing HttpTesterBase/HttpTester assertion API be reused unchanged by both tiers (ApiTesterBase sources its HttpClient from TestServer; AspireTesterBase sources it from the named Aspire resource).
  • HttpMock: a shared IHttpMockClient/IHttpMockRequest/IHttpMockResponse interface implemented by both Tier 1's MockHttpClient(Factory) and Tier 2's AspireHttpMockClient (backed by a real WireMock.Net resource) - the same fluent stubbing API, and the same YAML/JSON config schema (WithRequestsFromResourceAsync), works against either tier.
  • External dependency mocking: UnitTestEx's recommended pattern is to self-host WireMock.Net as an ordinary Aspire project resource (Docker-free) rather than the official WireMock.Net.Aspire package's container resource (which remains fully supported for teams already standardized on it). UnitTestEx.Aspire ships JsonElementComparerMatcher (a custom WireMock.Net matcher giving genuine JSON semantic-comparison parity with Tier 1) and WireMockConsole.RunAsync (collapses the self-hosted mock host's Program.cs boilerplate to one line).
  • Per-component mocking across processes: no DI reach-in equivalent exists (as anticipated) - use environment/config-driven test hooks per project, resource swaps, or Tier 1 where deep DI control of one service is the actual goal.

Notes

  • Playwright/UI-testing against Tier 2 resources needed no dedicated implementation or doc section - it is an ordinary consequence of Tier 2 resources being real, reachable URLs, not a UnitTestEx feature. A one-line footnote pointing to Microsoft's own Aspire + Playwright guide was added to the README instead.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions