Skip to content

feat: add CloudShop Aspire + TUnit example project - #4761

Merged
thomhurst merged 10 commits into
mainfrom
examples/cloudshop-aspire-tunit
Feb 14, 2026
Merged

feat: add CloudShop Aspire + TUnit example project#4761
thomhurst merged 10 commits into
mainfrom
examples/cloudshop-aspire-tunit

Conversation

@thomhurst

Copy link
Copy Markdown
Owner

Summary

  • Adds a comprehensive example project under examples/CloudShop/ showcasing TUnit integration testing with .NET Aspire
  • Near-real-world e-commerce microservices platform with PostgreSQL, Redis, RabbitMQ, REST API, background worker, and web frontend
  • TUnit test project demonstrates 15+ features including nested [ClassDataSource] injection chains, [MatrixDataSource] combinatorial testing, [CombinedDataSources], [DependsOn] workflow chains, [GenerateAssertion] custom assertions, parallelism controls, and more

Application Architecture

ProjectPurpose
CloudShop.AppHostAspire orchestration (PostgreSQL, Redis, RabbitMQ + all services)
CloudShop.ApiREST API: Products, Orders, Auth (EF Core, JWT, Redis caching, RabbitMQ)
CloudShop.WorkerBackground service consuming RabbitMQ for order fulfillment
CloudShop.WebMinimal frontend calling the API
CloudShop.SharedDTOs, models, events
CloudShop.TestsTUnit test project (the main showcase)

TUnit Features Demonstrated

FeatureWhere
[ClassDataSource<T>] with nested injection (3 levels)Infrastructure fixtures (App → DB/Redis/RabbitMQ → Auth clients → Seeded data)
SharedType.PerTestSession / PerClassAll fixtures
[MethodDataSource] with Func<T>Product, Order, Auth data sources
[MatrixDataSource] + [Matrix]ProductSearchTests (27 combos), OrderPlacementTests (9 combos)
[CombinedDataSources]AuthorizationTests (role × endpoint Cartesian product)
[DependsOn] chainOrderWorkflowTests (Create → Pay → Fulfill → DB Verify)
[GenerateAssertion]7 custom HTTP assertions (IsCreated, IsForbidden, HasJsonContent, etc.)
[NotInParallel]Cache, Workflow, Messaging tests
[ParallelLimiter<T>]LoadTests with custom 10/20 concurrent limits
[Repeat(N)]LoadTests (50/20/30 iterations)
[Retry(N)]OrderEventTests, ResilienceTests
[Timeout] + CancellationTokenAsync worker verification tests
[Category]Integration, E2E, Performance, Resilience, etc.
[Before]/[After]/[AfterEvery] hooksAssembly setup, per-test result logging
IAsyncInitializer / IAsyncDisposableAll infrastructure fixtures
TestContext metadataTestHooks accessing result state, display name, duration

Nested ClassDataSource Dependency Graph

DistributedAppFixture (PerTestSession) ← starts entire Aspire app
├── DatabaseFixture ← gets Postgres connection
├── RedisFixture ← gets Redis connection
├── RabbitMqFixture ← gets RabbitMQ connection
├── ApiClientFixture ← unauthenticated HTTP client
├── AdminApiClient ← authenticates as admin via JWT
├── CustomerApiClient ← authenticates as customer via JWT
└── SeededDatabaseFixture ← seeds test data via AdminApiClient

Test plan

  • Solution builds with 0 errors, 0 warnings
  • Verify example works with Docker running (requires PostgreSQL, Redis, RabbitMQ containers)
  • Review test patterns for clarity and correctness

🤖 Generated with Claude Code

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@thomhurst@github-advanced-security